Eclipse SUMO - Simulation of Urban MObility
Loading...
Searching...
No Matches
GNERoute.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-2023 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>
35
36#include "GNERoute.h"
37
38// ===========================================================================
39// FOX callback mapping
40// ===========================================================================
44
45// Object implementation
46FXIMPLEMENT(GNERoute::GNERoutePopupMenu, GUIGLObjectPopupMenu, GNERoutePopupMenuMap, ARRAYNUMBER(GNERoutePopupMenuMap))
47
48// ===========================================================================
49// GNERoute::GNERoutePopupMenu - methods
50// ===========================================================================
51
55
56
58
59
60long
62 GNERoute* route = static_cast<GNERoute*>(myObject);
63 GNEUndoList* undoList = route->myNet->getViewNet()->getUndoList();
64 undoList->begin(GUIIcon::ROUTE, "apply distance along route");
65 double dist = (route->getParentEdges().size() > 0) ? route->getParentEdges().front()->getNBEdge()->getDistance() : 0;
66 for (GNEEdge* edge : route->getParentEdges()) {
67 undoList->changeAttribute(new GNEChange_Attribute(edge, SUMO_ATTR_DISTANCE, toString(dist), edge->getAttribute(SUMO_ATTR_DISTANCE)));
68 dist += edge->getNBEdge()->getFinalLength();
69 }
70 undoList->end();
71 return 1;
72}
73
74// ===========================================================================
75// GNERoute - methods
76// ===========================================================================
77
79 GNEDemandElement("", net, GLO_ROUTE, tag, GUIIconSubSys::getIcon(GUIIcon::ROUTE),
81{}, {}, {}, {}, {}, {}),
83myColor(RGBColor::YELLOW),
84myRepeat(0),
85myCycleTime(0),
86myVClass(SVC_PASSENGER) {
87 // reset default values
88 resetDefaultValues();
89}
90
91
93 GNEDemandElement(net->getAttributeCarriers()->generateDemandElementID(SUMO_TAG_ROUTE), net, GLO_ROUTE, SUMO_TAG_ROUTE,
94 GUIIconSubSys::getIcon(GUIIcon::ROUTE),
95 GNEPathManager::PathElement::Options::DEMAND_ELEMENT | GNEPathManager::PathElement::Options::ROUTE,
96{}, {}, {}, {}, {}, {}),
98myColor(RGBColor::YELLOW),
99myRepeat(0),
100myCycleTime(0),
101myVClass(SVC_PASSENGER) {
102 // reset default values
103 resetDefaultValues();
104}
105
106
107GNERoute::GNERoute(GNENet* net, const std::string& id, SUMOVehicleClass vClass, const std::vector<GNEEdge*>& edges,
108 const RGBColor& color, const int repeat, const SUMOTime cycleTime, const Parameterised::Map& parameters) :
110 GNEPathManager::PathElement::Options::DEMAND_ELEMENT | GNEPathManager::PathElement::Options::ROUTE,
111{}, edges, {}, {}, {}, {}),
112Parameterised(parameters),
113myColor(color),
114myRepeat(repeat),
115myCycleTime(cycleTime),
116myVClass(vClass) {
117}
118
119
120GNERoute::GNERoute(GNENet* net, GNEDemandElement* vehicleParent, const std::vector<GNEEdge*>& edges,
121 const RGBColor& color, const int repeat, const SUMOTime cycleTime, const Parameterised::Map& parameters) :
123 GNEPathManager::PathElement::Options::DEMAND_ELEMENT | GNEPathManager::PathElement::Options::ROUTE,
124{}, edges, {}, {}, {vehicleParent}, {}),
125Parameterised(parameters),
126myColor(color),
127myRepeat(repeat),
128myCycleTime(cycleTime),
129myVClass(vehicleParent->getVClass()) {
130}
131
132
134 GNEDemandElement(route, route->getNet(), GLO_ROUTE, SUMO_TAG_ROUTE, GUIIconSubSys::getIcon(GUIIcon::ROUTE),
135 GNEPathManager::PathElement::Options::DEMAND_ELEMENT | GNEPathManager::PathElement::Options::ROUTE,
136{}, route->getParentEdges(), {}, {}, {}, {}),
138myColor(route->getColor()),
139myRepeat(parse<int>(route->getAttribute(SUMO_ATTR_REPEAT))),
140myCycleTime(parse<SUMOTime>(route->getAttribute(SUMO_ATTR_CYCLETIME))),
141myVClass(route->getVClass()) {
142}
143
144
146
147
150 return nullptr;
151}
152
153
156 GUIGLObjectPopupMenu* ret = new GNERoutePopupMenu(app, parent, *this);
157 // build header
158 buildPopupHeader(ret, app);
159 // build menu command for center button and copy cursor position to clipboard
161 buildPositionCopyEntry(ret, app);
162 // buld menu commands for names
163 GUIDesigns::buildFXMenuCommand(ret, "Copy " + getTagStr() + " name to clipboard", nullptr, ret, MID_COPY_NAME);
164 GUIDesigns::buildFXMenuCommand(ret, "Copy " + getTagStr() + " typed name to clipboard", nullptr, ret, MID_COPY_TYPED_NAME);
165 new FXMenuSeparator(ret);
166 // build selection and show parameters menu
169 // show option to open demand element dialog
170 if (myTagProperty.hasDialog()) {
171 GUIDesigns::buildFXMenuCommand(ret, "Open " + getTagStr() + " Dialog", getACIcon(), &parent, MID_OPEN_ADDITIONAL_DIALOG);
172 new FXMenuSeparator(ret);
173 }
174 GUIDesigns::buildFXMenuCommand(ret, "Cursor position in view: " + toString(getPositionInView().x()) + "," + toString(getPositionInView().y()), nullptr, nullptr, 0);
175 new FXMenuSeparator(ret);
176 GUIDesigns::buildFXMenuCommand(ret, "Apply distance along route", nullptr, ret, MID_GNE_ROUTE_APPLY_DISTANCE);
177 // route length
179 return ret;
180}
181
182
183void
185 device.openTag(SUMO_TAG_ROUTE);
186 // write id only for non-embedded routes
188 device.writeAttr(SUMO_ATTR_ID, getID());
189 }
193 }
194 if (myRepeat != 0) {
196 }
197 if (myCycleTime != 0) {
199 }
200 // write sorted stops
202 // write stops
203 for (const auto& demandElement : getChildDemandElements()) {
204 if (demandElement->getTagProperty().isStop() || demandElement->getTagProperty().isWaypoint()) {
205 demandElement->writeDemandElement(device);
206 }
207 }
208 }
209 // write parameters
210 writeParams(device);
211 // close tag
212 device.closeTag();
213}
214
215
218 // get sorted stops and check number
219 std::vector<GNEDemandElement*> stops;
220 for (const auto& routeChild : getChildDemandElements()) {
221 if (routeChild->getTagProperty().isStop()) {
222 stops.push_back(routeChild);
223 }
224 }
225 if (getInvalidStops().size() > 0) {
227 }
228 // check parent edges
229 if ((getParentEdges().size() == 2) && (getParentEdges().at(0) == getParentEdges().at(1))) {
230 // from and to are the same edges, then return true
231 return Problem::OK;
232 } else if (getParentEdges().size() > 0) {
233 // check that exist a connection between every edge
234 if (isRouteValid(getParentEdges()).size() > 0) {
236 } else {
237 return Problem::OK;
238 }
239 } else {
241 }
242}
243
244
245std::string
247 // get sorted stops and check number
248 std::vector<GNEDemandElement*> stops;
249 for (const auto& routeChild : getChildDemandElements()) {
250 if (routeChild->getTagProperty().isStop()) {
251 stops.push_back(routeChild);
252 }
253 }
254 const auto invalidStops = getInvalidStops();
255 if (invalidStops.size() > 0) {
256 return toString(invalidStops.size()) + " stops are outside of route (downstream)";
257 }
258 // return string with the problem obtained from isRouteValid
260}
261
262
263void
265 // currently the only solution is removing Route
266}
267
268
271 return myVClass;
272}
273
274
275const RGBColor&
278 return myColor;
279 } else if ((getParentDemandElements().size() > 0) && (getParentDemandElements().front()->getColor() != RGBColor::INVISIBLE)) {
280 return getParentDemandElements().front()->getColor();
281 } else if ((getChildDemandElements().size() > 0) && (getChildDemandElements().front()->getColor() != RGBColor::INVISIBLE)) {
282 return getChildDemandElements().front()->getColor();
283 } else {
284 return RGBColor::YELLOW;
285 }
286}
287
288
289void
291 // compute geometry
293 // update child demand elementss
294 for (const auto& demandElement : getChildDemandElements()) {
295 if (!demandElement->getTagProperty().isStopPerson() && !demandElement->getTagProperty().isStop()) {
296 demandElement->updateGeometry();
297 }
298 }
299}
300
301
306
307
308std::string
310 return getParentEdges().front()->getID();
311}
312
313
314double
318
319
322 Boundary routeBoundary;
323 // return the combination of all parent edges's boundaries
324 for (const auto& i : getParentEdges()) {
325 routeBoundary.add(i->getCenteringBoundary());
326 }
327 // check if is valid
328 if (routeBoundary.isInitialised()) {
329 return routeBoundary;
330 } else {
331 return Boundary(-0.1, -0.1, 0.1, 0.1);
332 }
333}
334
335
336void
337GNERoute::splitEdgeGeometry(const double /*splitPosition*/, const GNENetworkElement* originalElement, const GNENetworkElement* newElement, GNEUndoList* undoList) {
338 // obtain new list of route edges
339 std::string newRouteEdges = getNewListOfParents(originalElement, newElement);
340 // update route edges
341 if (newRouteEdges.size() > 0) {
342 setAttribute(SUMO_ATTR_EDGES, newRouteEdges, undoList);
343 }
344}
345
346
347void
349 // Routes are drawn in drawPartialGL
350}
351
352
353void
356 // get parent vehicle
357 const GNEDemandElement* parentVehicle = getParentDemandElements().at(0);
358 // declare lane vector
359 std::vector<GNELane*> lanes;
360 // get first and last path lane
361 GNELane* firstLane = parentVehicle->getFirstPathLane();
362 GNELane* lastLane = parentVehicle->getLastPathLane();
363 // insert first vehicle lane
364 if (firstLane) {
365 lanes.push_back(firstLane);
366 }
367 // add middle lanes
368 for (int i = 1; i < ((int)getParentEdges().size() - 1); i++) {
369 lanes.push_back(getParentEdges().at(i)->getLaneByAllowedVClass(getVClass()));
370 }
371 // insert last vehicle lane
372 if (lastLane) {
373 lanes.push_back(lastLane);
374 }
375 // calculate consecutive path using vClass of vehicle parent
377 } else {
378 // calculate path using SVC_PASSENGER
380 // if path is empty, then calculate path again using SVC_IGNORING
381 if (!myNet->getPathManager()->isPathValid(this)) {
383 }
384 }
385}
386
387
388void
389GNERoute::drawPartialGL(const GUIVisualizationSettings& s, const GNELane* lane, const GNEPathManager::Segment* segment, const double offsetFront) const {
390 // get inspected and front flags
391 const bool dottedElement = myNet->getViewNet()->isAttributeCarrierInspected(this) ||
392 (myNet->getViewNet()->getFrontAttributeCarrier() == this) ||
393 myNet->getViewNet()->drawDeleteContour(this, this) ||
394 myNet->getViewNet()->drawSelectContour(this, this) ||
395 (gPostDrawing.markedRoute == this);
396 // check conditions
400 myNet->getPathManager()->getPathDraw()->drawPathGeometry(dottedElement, lane, myTagProperty.getTag())) {
401 // get embedded route flag
402 const bool embedded = (myTagProperty.getTag() == GNE_TAG_ROUTE_EMBEDDED);
403 // get route width
404 const double routeWidth = getExaggeration(s) * (embedded ? s.widthSettings.embeddedRouteWidth : s.widthSettings.routeWidth);
405 // calculate startPos
406 const double geometryDepartPos = embedded ? (getParentDemandElements().at(0)->getAttributeDouble(SUMO_ATTR_DEPARTPOS) + getParentDemandElements().at(0)->getParentDemandElements().at(0)->getAttributeDouble(SUMO_ATTR_LENGTH)) : -1;
407 // get endPos
408 const double geometryEndPos = embedded ? getParentDemandElements().at(0)->getAttributeDouble(SUMO_ATTR_ARRIVALPOS) : -1;
409 // declare path geometry
410 GUIGeometry routeGeometry;
411 // update pathGeometry depending of first and last segment
412 if (segment->isFirstSegment() && segment->isLastSegment()) {
413 routeGeometry.updateGeometry(lane->getLaneGeometry().getShape(),
414 geometryDepartPos, geometryEndPos, // extrem positions
415 Position::INVALID, Position::INVALID); // extra positions
416 } else if (segment->isFirstSegment()) {
417 routeGeometry.updateGeometry(lane->getLaneGeometry().getShape(),
418 geometryDepartPos, -1, // extrem positions
419 Position::INVALID, Position::INVALID); // extra positions
420 } else if (segment->isLastSegment()) {
421 routeGeometry.updateGeometry(lane->getLaneGeometry().getShape(),
422 -1, geometryEndPos, // extrem positions
423 Position::INVALID, Position::INVALID); // extra positions
424 } else {
425 routeGeometry = lane->getLaneGeometry();
426 }
427 // obtain color
429 // avoid draw invisible elements
430 if (routeColor.alpha() != 0) {
431 // Start drawing adding an gl identificator
433 // Add a draw matrix
435 // Start with the drawing of the area traslating matrix to origin
436 myNet->getViewNet()->drawTranslateFrontAttributeCarrier(this, getType(), offsetFront + (embedded ? 0.1 : 0));
437 // Set color
438 GLHelper::setColor(routeColor);
439 // draw route geometry
440 GUIGeometry::drawGeometry(s, myNet->getViewNet()->getPositionInformation(), routeGeometry, routeWidth);
441 // Pop last matrix
443 // Draw name if isn't being drawn for selecting
445 drawName(getCenteringBoundary().getCenter(), s.scale, s.addName);
446 }
447 // Pop name
449 // check if we have to draw a red line to the next segment
450 if (segment->getNextSegment()) {
451 // push draw matrix
453 // Start with the drawing of the area traslating matrix to origin
455 // Set red color
457 // get firstPosition (last position of current lane shape)
458 const Position firstPosition = lane->getLaneShape().back();
459 // get lastPosition (first position of next lane shape)
460 const Position arrivalPos = segment->getNextSegment()->getPathElement()->getPathElementArrivalPos();
461 // draw box line
462 GLHelper::drawBoxLine(arrivalPos,
463 RAD2DEG(firstPosition.angleTo2D(arrivalPos)) - 90,
464 firstPosition.distanceTo2D(arrivalPos), .05);
465 // pop draw matrix
467 }
468 }
469 // check if mark this route
471 if ((gPostDrawing.markedRoute == nullptr) && myNet->getViewNet()->getViewParent()->getVehicleFrame()->shown() && templateAC &&
472 ((templateAC->getTagProperty().getTag() == SUMO_TAG_VEHICLE) || (templateAC->getTagProperty().getTag() == GNE_TAG_FLOW_ROUTE)) &&
473 (routeGeometry.getShape().distance2D(myNet->getViewNet()->getPositionInformation()) <= routeWidth)) {
475 }
476 // declare trim geometry to draw
477 const auto shape = (segment->isFirstSegment() || segment->isLastSegment() ? routeGeometry.getShape() : lane->getLaneShape());
478 // check if mouse is over element
479 mouseWithinGeometry(shape, routeWidth);
480 // inspect contour
483 }
484 // front contour
485 if (myNet->getViewNet()->getFrontAttributeCarrier() == this) {
487 }
488 // delete contour
489 if (myNet->getViewNet()->drawDeleteContour(this, this)) {
491 }
492 // select contour
493 if (myNet->getViewNet()->drawSelectContour(this, this)) {
495 }
496 // draw marked dotted contour
497 if (gPostDrawing.markedRoute == this) {
499 }
500 }
501}
502
503
504void
505GNERoute::drawPartialGL(const GUIVisualizationSettings& s, const GNELane* fromLane, const GNELane* toLane, const GNEPathManager::Segment* /*segment*/, const double offsetFront) const {
506 // get inspected and front flags
507 const bool dottedElement = myNet->getViewNet()->isAttributeCarrierInspected(this) ||
508 (myNet->getViewNet()->getFrontAttributeCarrier() == this) ||
509 myNet->getViewNet()->drawDeleteContour(this, this) ||
510 myNet->getViewNet()->drawSelectContour(this, this) ||
511 (gPostDrawing.markedRoute == this);
512 // check conditions
515 fromLane->getLane2laneConnections().exist(toLane) &&
517 myNet->getPathManager()->getPathDraw()->drawPathGeometry(dottedElement, fromLane, toLane, myTagProperty.getTag())) {
518 // get embedded route flag
519 const bool embedded = (myTagProperty.getTag() == GNE_TAG_ROUTE_EMBEDDED);
520 // get route width
521 const double routeWidth = getExaggeration(s) * (embedded ? s.widthSettings.embeddedRouteWidth : s.widthSettings.routeWidth);
522 // obtain lane2lane geometry
523 const GUIGeometry& lane2laneGeometry = fromLane->getLane2laneConnections().getLane2laneGeometry(toLane);
524 // obtain color
526 // Start drawing adding an gl identificator
528 // Add a draw matrix
530 // Start with the drawing of the area traslating matrix to origin
531 myNet->getViewNet()->drawTranslateFrontAttributeCarrier(this, getType(), offsetFront + (embedded ? 0.1 : 0));
532 // Set color
533 GLHelper::setColor(routeColor);
534 // draw lane2lane
535 GUIGeometry::drawGeometry(s, myNet->getViewNet()->getPositionInformation(), lane2laneGeometry, routeWidth);
536 // Pop last matrix
538 // Pop name
540 // draw lock icon
542 // check if mark this route
544 if ((gPostDrawing.markedRoute == nullptr) && myNet->getViewNet()->getViewParent()->getVehicleFrame()->shown() && templateAC &&
545 ((templateAC->getTagProperty().getTag() == SUMO_TAG_VEHICLE) || (templateAC->getTagProperty().getTag() == GNE_TAG_FLOW_ROUTE)) &&
546 (lane2laneGeometry.getShape().distance2D(myNet->getViewNet()->getPositionInformation()) <= routeWidth)) {
548 }
549 // check if mouse is over element
551 // inspect contour
554 routeWidth, 1, false, false);
555 }
556 // front contour
557 if (myNet->getViewNet()->getFrontAttributeCarrier() == this) {
559 routeWidth, 1, false, false);
560 }
561 // delete contour
562 if (myNet->getViewNet()->drawDeleteContour(this, this)) {
564 routeWidth, 1, false, false);
565 }
566 // select contour
567 if (myNet->getViewNet()->drawSelectContour(this, this)) {
569 routeWidth, 1, false, false);
570 }
571 // green contour
572 if (gPostDrawing.markedRoute == this) {
574 routeWidth, 1, false, false);
575 }
576 }
577}
578
579
580GNELane*
583 return getParentEdges().front()->getLaneByAllowedVClass(SVC_PASSENGER);
584 } else {
585 return getParentDemandElements().at(0)->getFirstPathLane();
586 }
587}
588
589
590GNELane*
593 return getParentEdges().back()->getLaneByAllowedVClass(SVC_PASSENGER);
594 } else {
595 return getParentDemandElements().at(0)->getLastPathLane();
596 }
597}
598
599
600std::string
602 switch (key) {
603 case SUMO_ATTR_ID:
604 return getMicrosimID();
605 case SUMO_ATTR_EDGES:
606 return parseIDs(getParentEdges());
607 case SUMO_ATTR_COLOR:
609 return toString(myColor);
610 } else {
611 return "";
612 }
613 case SUMO_ATTR_REPEAT:
614 return toString(myRepeat);
616 return time2string(myCycleTime);
620 return getParametersStr();
621 default:
622 throw InvalidArgument(getTagStr() + " doesn't have an attribute of type '" + toString(key) + "'");
623 }
624}
625
626
627double
629 switch (key) {
631 return 0;
633 return getParentEdges().back()->getLanes().front()->getLaneShape().length2D();
634 default:
635 throw InvalidArgument(getTagStr() + " doesn't have an attribute of type '" + toString(key) + "'");
636 }
637}
638
639
642 switch (key) {
644 return getParentEdges().front()->getLanes().front()->getLaneShape().front();
646 return getParentEdges().back()->getLanes().front()->getLaneShape().back();
647 default:
648 throw InvalidArgument(getTagStr() + " doesn't have an attribute of type '" + toString(key) + "'");
649 }
650}
651
652
653void
654GNERoute::setAttribute(SumoXMLAttr key, const std::string& value, GNEUndoList* undoList) {
655 if (value == getAttribute(key)) {
656 return; //avoid needless changes, later logic relies on the fact that attributes have changed
657 }
658 switch (key) {
659 case SUMO_ATTR_ID:
660 case SUMO_ATTR_COLOR:
661 case SUMO_ATTR_REPEAT:
665 undoList->changeAttribute(new GNEChange_Attribute(this, key, value));
666 break;
667 // special case due depart and arrival edge vehicles
668 case SUMO_ATTR_EDGES: {
669 // extract all vehicle childrens
670 std::vector<GNEDemandElement*> vehicles;
671 for (const auto& childDemandElement : getChildDemandElements()) {
672 if (childDemandElement->getTagProperty().isVehicle()) {
673 vehicles.push_back(childDemandElement);
674 }
675 }
676 // check vehicles
677 if (vehicles.size() > 0) {
678 undoList->begin(GUIIcon::ROUTE, "reset start and end edges");
679 for (const auto& vehicle : vehicles) {
680 undoList->changeAttribute(new GNEChange_Attribute(vehicle, SUMO_ATTR_DEPARTEDGE, ""));
681 undoList->changeAttribute(new GNEChange_Attribute(vehicle, SUMO_ATTR_ARRIVALEDGE, ""));
682 }
683 undoList->changeAttribute(new GNEChange_Attribute(this, key, value));
684 undoList->end();
686 undoList->begin(GUIIcon::ROUTE, "reset start and end edges");
689 undoList->changeAttribute(new GNEChange_Attribute(this, key, value));
690 undoList->end();
691 } else {
692 // just change edges
693 undoList->changeAttribute(new GNEChange_Attribute(this, key, value));
694 }
695 break;
696 }
697 default:
698 throw InvalidArgument(getTagStr() + " doesn't have an attribute of type '" + toString(key) + "'");
699 }
700}
701
702
703bool
704GNERoute::isValid(SumoXMLAttr key, const std::string& value) {
705 switch (key) {
706 case SUMO_ATTR_ID:
707 return isValidDemandElementID(value);
708 case SUMO_ATTR_EDGES:
709 if (canParse<std::vector<GNEEdge*> >(myNet, value, false)) {
710 // all edges exist, then check if compounds a valid route
711 return isRouteValid(parse<std::vector<GNEEdge*> >(myNet, value)).empty();
712 } else {
713 return false;
714 }
715 case SUMO_ATTR_COLOR:
716 if (value.empty()) {
717 return true;
718 } else {
719 return canParse<RGBColor>(value);
720 }
721 case SUMO_ATTR_REPEAT:
722 return canParse<int>(value);
724 if (canParse<SUMOTime>(value)) {
725 return (parse<SUMOTime>(value) >= 0);
726 } else {
727 return false;
728 }
730 return canParse<bool>(value);
733 default:
734 throw InvalidArgument(getTagStr() + " doesn't have an attribute of type '" + toString(key) + "'");
735 }
736}
737
738
739std::string
741 return getTagStr();
742}
743
744
745std::string
747 return getTagStr() + ": " + getAttribute(SUMO_ATTR_ID) ;
748}
749
750
755
756
757std::string
758GNERoute::isRouteValid(const std::vector<GNEEdge*>& edges) {
759 if (edges.size() == 0) {
760 // routes cannot be empty
761 return ("list of route edges cannot be empty");
762 } else if (edges.size() == 1) {
763 // routes with a single edge are valid, then return an empty string
764 return ("");
765 } else {
766 // iterate over edges to check that compounds a chain
767 auto it = edges.begin();
768 while (it != edges.end() - 1) {
769 const GNEEdge* currentEdge = *it;
770 const GNEEdge* nextEdge = *(it + 1);
771 // same consecutive edges aren't allowed
772 if (currentEdge->getID() == nextEdge->getID()) {
773 return ("consecutive duplicated edges (" + currentEdge->getID() + ") aren't allowed in a route");
774 }
775 // obtain outgoing edges of currentEdge
776 const std::vector<GNEEdge*>& outgoingEdges = currentEdge->getToJunction()->getGNEOutgoingEdges();
777 // check if nextEdge is in outgoingEdges
778 if (std::find(outgoingEdges.begin(), outgoingEdges.end(), nextEdge) == outgoingEdges.end()) {
779 return ("Edges '" + currentEdge->getID() + "' and '" + nextEdge->getID() + "' aren't consecutives");
780 }
781 it++;
782 }
783 // all edges consecutives, then return an empty string
784 return ("");
785 }
786}
787
788// ===========================================================================
789// private
790// ===========================================================================
791
792void
793GNERoute::setAttribute(SumoXMLAttr key, const std::string& value) {
794 switch (key) {
795 case SUMO_ATTR_ID:
796 // update microsimID
797 setMicrosimID(value);
798 break;
799 case SUMO_ATTR_EDGES:
801 // compute route
803 break;
804 case SUMO_ATTR_COLOR:
805 if (value.empty()) {
807 } else {
808 myColor = parse<RGBColor>(value);
809 }
810 break;
811 case SUMO_ATTR_REPEAT:
812 myRepeat = parse<int>(value);
813 break;
815 myCycleTime = string2time(value);
816 break;
818 if (parse<bool>(value)) {
820 } else {
822 }
823 break;
825 setParametersStr(value);
826 break;
827 default:
828 throw InvalidArgument(getTagStr() + " doesn't have an attribute of type '" + toString(key) + "'");
829 }
830}
831
832
833void
834GNERoute::setMoveShape(const GNEMoveResult& /*moveResult*/) {
835 // routes cannot be moved
836}
837
838
839void
840GNERoute::commitMoveShape(const GNEMoveResult& /*moveResult*/, GNEUndoList* /*undoList*/) {
841 // routes cannot be moved
842}
843
844/****************************************************************************/
FXDEFMAP(GNERoute::GNERoutePopupMenu) GNERoutePopupMenuMap[]
long long int SUMOTime
Definition GUI.h:36
@ MID_COPY_TYPED_NAME
Copy typed object name - popup entry.
Definition GUIAppEnum.h:450
@ MID_OPEN_ADDITIONAL_DIALOG
open additional dialog (used in netedit)
Definition GUIAppEnum.h:462
@ MID_COPY_NAME
Copy object name - popup entry.
Definition GUIAppEnum.h:448
@ MID_GNE_ROUTE_APPLY_DISTANCE
apply distance
@ GLO_ROUTE
a route
GUIPostDrawing gPostDrawing
GUIIcon
An enumeration of icons used by the gui applications.
Definition GUIIcons.h:33
#define RAD2DEG(x)
Definition GeomHelper.h:36
SUMOTime string2time(const std::string &r)
convert string to SUMOTime
Definition SUMOTime.cpp:46
std::string time2string(SUMOTime t, bool humanReadable)
convert SUMOTime to string (independently of global format setting)
Definition SUMOTime.cpp:69
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_VEHICLE
description of a vehicle
@ GNE_TAG_FLOW_ROUTE
a flow definition using a route instead of a from-to edges route
@ SUMO_TAG_ROUTE
begin/end of the description of a route
@ GNE_TAG_ROUTE_EMBEDDED
embedded route
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:78
bool isInitialised() const
check if Boundary is Initialised
Definition Boundary.cpp:216
static void setColor(const RGBColor &c)
Sets the gl-color to this value.
Definition GLHelper.cpp:583
static void pushName(unsigned int name)
push Name
Definition GLHelper.cpp:139
static void popMatrix()
pop matrix
Definition GLHelper.cpp:130
static void drawBoxLine(const Position &beg, double rot, double visLength, double width, double offset=0)
Draws a thick line.
Definition GLHelper.cpp:277
static void popName()
pop Name
Definition GLHelper.cpp:148
static void pushMatrix()
push matrix
Definition GLHelper.cpp:117
const std::string getID() const
get ID (all Attribute Carriers have one)
bool isAttributeCarrierSelected() const
check if attribute carrier is selected
FXIcon * getACIcon() const
get FXIcon associated to this AC
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.
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 belong to GNENet but has influence in the simulation.
void buildMenuCommandRouteLength(GUIGLObjectPopupMenu *ret) const
build menu command route length
void replaceDemandParentEdges(const std::string &value)
replace demand parent edges
std::vector< GNEDemandElement * > getInvalidStops() const
get invalid stops
virtual GNELane * getLastPathLane() const =0
get last path lane
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
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:136
const GNELane2laneConnection & getLane2laneConnections() const
get Lane2laneConnection struct
Definition GNELane.cpp:829
Position getPositionInView() const
Returns position of hierarchical element in view.
Definition GNELane.cpp:235
const GUIGeometry & getLaneGeometry() const
Definition GNELane.cpp:130
move operation
move result
A NBNetBuilder extended by visualisation and editing capabilities.
Definition GNENet.h:42
GNEPathManager * getPathManager()
get path manager
Definition GNENet.cpp:132
GNEViewNet * getViewNet() const
get view net
Definition GNENet.cpp:2030
bool drawPathGeometry(const bool dottedElement, const GNELane *lane, SumoXMLTag tag)
check if path element geometry must be drawn in the given lane
virtual Position getPathElementArrivalPos() const =0
get path element arrival position
PathElement()=delete
invalidate default constructor
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:57
long onCmdApplyDistance(FXObject *, FXSelector, void *)
Called to modify edge distance values along the route.
Definition GNERoute.cpp:61
std::string getHierarchyName() const
get Hierarchy Name (Used in AC Hierarchy)
Definition GNERoute.cpp:746
void fixDemandElementProblem()
fix demand element problem (by default throw an exception, has to be reimplemented in children)
Definition GNERoute.cpp:264
double getExaggeration(const GUIVisualizationSettings &s) const
return exaggeration associated with this GLObject
Definition GNERoute.cpp:315
GNELane * getLastPathLane() const
get last path lane
Definition GNERoute.cpp:591
Position getPositionInView() const
Returns position of additional in view.
Definition GNERoute.cpp:303
SUMOVehicleClass myVClass
SUMOVehicleClass (Only used for drawing)
Definition GNERoute.h:270
std::string getParentName() const
Returns the name of the parent object.
Definition GNERoute.cpp:309
SUMOTime myCycleTime
cycleTime
Definition GNERoute.h:267
std::string getPopUpID() const
get PopPup ID (Used in AC Hierarchy)
Definition GNERoute.cpp:740
std::string getAttribute(SumoXMLAttr key) const
inherited from GNEAttributeCarrier
Definition GNERoute.cpp:601
Position getAttributePosition(SumoXMLAttr key) const
Definition GNERoute.cpp:641
void updateGeometry()
update pre-computed geometry information
Definition GNERoute.cpp:290
GUIGLObjectPopupMenu * getPopUpMenu(GUIMainWindow &app, GUISUMOAbstractView &parent)
Returns an own popup-menu.
Definition GNERoute.cpp:155
void splitEdgeGeometry(const double splitPosition, const GNENetworkElement *originalElement, const GNENetworkElement *newElement, GNEUndoList *undoList)
split geometry
Definition GNERoute.cpp:337
void setMoveShape(const GNEMoveResult &moveResult)
set move shape
Definition GNERoute.cpp:834
const Parameterised::Map & getACParametersMap() const
get parameters map
Definition GNERoute.cpp:752
GNELane * getFirstPathLane() const
get first path lane
Definition GNERoute.cpp:581
double getAttributeDouble(SumoXMLAttr key) const
Definition GNERoute.cpp:628
GNEMoveOperation * getMoveOperation()
get move operation
Definition GNERoute.cpp:149
void commitMoveShape(const GNEMoveResult &moveResult, GNEUndoList *undoList)
commit move shape
Definition GNERoute.cpp:840
SUMOVehicleClass getVClass() const
Definition GNERoute.cpp:270
GNERoute(SumoXMLTag tag, GNENet *net)
default constructor
Definition GNERoute.cpp:78
void drawPartialGL(const GUIVisualizationSettings &s, const GNELane *lane, const GNEPathManager::Segment *segment, const double offsetFront) const
Draws partial object.
Definition GNERoute.cpp:389
Boundary getCenteringBoundary() const
Returns the boundary to which the view shall be centered in order to show the object.
Definition GNERoute.cpp:321
bool isValid(SumoXMLAttr key, const std::string &value)
method for checking if the key and their conrrespond attribute are valids
Definition GNERoute.cpp:704
void drawGL(const GUIVisualizationSettings &s) const
Draws the object.
Definition GNERoute.cpp:348
static std::string isRouteValid(const std::vector< GNEEdge * > &edges)
check if a route is valid
Definition GNERoute.cpp:758
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:654
int myRepeat
repeat
Definition GNERoute.h:264
void computePathElement()
compute pathElement
Definition GNERoute.cpp:354
std::string getDemandElementProblem() const
return a string with the current demand element problem (by default empty, can be reimplemented in ch...
Definition GNERoute.cpp:246
RGBColor myColor
route color
Definition GNERoute.h:261
void writeDemandElement(OutputDevice &device) const
write demand element element into a xml file
Definition GNERoute.cpp:184
~GNERoute()
destructor
Definition GNERoute.cpp:145
const RGBColor & getColor() const
get color
Definition GNERoute.cpp:276
Problem isDemandElementValid() const
check if current demand element is valid to be writed into XML (by default true, can be reimplemented...
Definition GNERoute.cpp:217
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
GNEAttributeCarrier * getCurrentTemplateAC() const
get current templateAC
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
GNETagSelector * getVehicleTagSelector() const
get vehicle tag selector (needed for transform vehicles)
const GNEViewNetHelper::DataViewOptions & getDataViewOptions() const
get data view options
const GNEAttributeCarrier * getFrontAttributeCarrier() const
get front attributeCarrier
bool drawSelectContour(const GUIGlObject *GLObject, const GNEAttributeCarrier *AC) const
check if draw select contour
bool drawDeleteContour(const GUIGlObject *GLObject, const GNEAttributeCarrier *AC) const
check if draw delete contour
const GNEViewNetHelper::NetworkViewOptions & getNetworkViewOptions() const
get network view options
void drawTranslateFrontAttributeCarrier(const GNEAttributeCarrier *AC, double typeOrLayer, const double extraOffset=0)
draw front attributeCarrier
GNEViewParent * getViewParent() const
get the net object
GNEUndoList * getUndoList() const
get the undoList object
void buildSelectionACPopupEntry(GUIGLObjectPopupMenu *ret, GNEAttributeCarrier *AC)
Builds an entry which allows to (de)select the object.
bool isAttributeCarrierInspected(const GNEAttributeCarrier *AC) const
check if attribute carrier is being inspected
const GNEViewNetHelper::DemandViewOptions & getDemandViewOptions() const
get demand view options
GNEVehicleFrame * getVehicleFrame() const
get frame for DEMAND_VEHICLE
static FXMenuCommand * buildFXMenuCommand(FXComposite *p, const std::string &text, FXIcon *icon, FXObject *tgt, FXSelector sel)
build menu command
static void drawDottedContourShape(const GUIVisualizationSettings &s, const DottedContourType type, const PositionVector &shape, const double width, const double exaggeration, const bool drawFirstExtrem, const bool drawLastExtrem)
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
const std::string & getMicrosimID() const
Returns the id of the object as known to microsim.
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.
bool mouseWithinGeometry(const Position center, const double radius) const
check if mouse is within elements geometry (for circles)
void buildPositionCopyEntry(GUIGLObjectPopupMenu *ret, const GUIMainWindow &app) const
Builds an entry which allows to copy the cursor position if geo projection is used,...
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
const GUIGlObject * markedRoute
marked Route (used in create vehicle mode)
virtual 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.
OutputDevice & writeAttr(const SumoXMLAttr attr, const T &val)
writes a named attribute
OutputDevice & openTag(const std::string &xmlElement)
Opens an XML tag.
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.
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|....
std::map< std::string, std::string > Map
parameters map
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"
const Parameterised::Map & getParametersMap() const
Returns the inner key/value map.
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".
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:300
double distanceTo2D(const Position &p2) const
returns the euclidean distance in the x-y-plane
Definition Position.h:254
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:264
double distance2D(const Position &p, bool perpendicular=false) const
closest 2D-distance to point p (or -1 if perpendicular is true and the point is beyond this vector)
unsigned char alpha() const
Returns the alpha-amount of the color.
Definition RGBColor.cpp:92
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