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>
35
36#include "GNERoute.h"
37
38// ===========================================================================
39// FOX callback mapping
40// ===========================================================================
41FXDEFMAP(GNERoute::GNERoutePopupMenu) GNERoutePopupMenuMap[] = {
43};
44
45// Object implementation
46FXIMPLEMENT(GNERoute::GNERoutePopupMenu, GUIGLObjectPopupMenu, GNERoutePopupMenuMap, ARRAYNUMBER(GNERoutePopupMenuMap))
47
48// ===========================================================================
49// GNERoute::GNERoutePopupMenu - methods
50// ===========================================================================
51
53 GUIGLObjectPopupMenu(app, parent, o) {
54}
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 const auto sortedStops = getSortedStops(getParentEdges());
203 for (const auto& stop : sortedStops) {
204 stop->writeDemandElement(device);
205 }
206 }
207 // write parameters
208 writeParams(device);
209 // close tag
210 device.closeTag();
211}
212
213
216 // get sorted stops and check number
217 std::vector<GNEDemandElement*> stops;
218 for (const auto& routeChild : getChildDemandElements()) {
219 if (routeChild->getTagProperty().isStop()) {
220 stops.push_back(routeChild);
221 }
222 }
223 const auto sortedStops = getSortedStops(getParentEdges());
224 if (sortedStops.size() != stops.size()) {
226 }
227 // check parent edges
228 if ((getParentEdges().size() == 2) && (getParentEdges().at(0) == getParentEdges().at(1))) {
229 // from and to are the same edges, then return true
230 return Problem::OK;
231 } else if (getParentEdges().size() > 0) {
232 // check that exist a connection between every edge
233 if (isRouteValid(getParentEdges()).size() > 0) {
235 } else {
236 return Problem::OK;
237 }
238 } else {
240 }
241}
242
243
244std::string
246 // get sorted stops and check number
247 std::vector<GNEDemandElement*> stops;
248 for (const auto& routeChild : getChildDemandElements()) {
249 if (routeChild->getTagProperty().isStop()) {
250 stops.push_back(routeChild);
251 }
252 }
253 const auto sortedStops = getSortedStops(getParentEdges());
254 if (sortedStops.size() != stops.size()) {
255 return toString(stops.size() - sortedStops.size()) + " stops are outside of route (downstream)";
256 }
257 // return string with the problem obtained from isRouteValid
259}
260
261
262void
264 // currently the only solution is removing Route
265}
266
267
270 return myVClass;
271}
272
273
274const RGBColor&
277 return myColor;
278 } else if ((getParentDemandElements().size() > 0) && (getParentDemandElements().front()->getColor() != RGBColor::INVISIBLE)) {
279 return getParentDemandElements().front()->getColor();
280 } else if ((getChildDemandElements().size() > 0) && (getChildDemandElements().front()->getColor() != RGBColor::INVISIBLE)) {
281 return getChildDemandElements().front()->getColor();
282 } else {
283 return RGBColor::YELLOW;
284 }
285}
286
287
288void
290 // compute geometry
292 // update child demand elementss
293 for (const auto& demandElement : getChildDemandElements()) {
294 if (!demandElement->getTagProperty().isStopPerson() && !demandElement->getTagProperty().isStop()) {
295 demandElement->updateGeometry();
296 }
297 }
298}
299
300
304}
305
306
307std::string
309 return getParentEdges().front()->getID();
310}
311
312
313double
315 return s.vehicleSize.getExaggeration(s, this);
316}
317
318
321 Boundary routeBoundary;
322 // return the combination of all parent edges's boundaries
323 for (const auto& i : getParentEdges()) {
324 routeBoundary.add(i->getCenteringBoundary());
325 }
326 // check if is valid
327 if (routeBoundary.isInitialised()) {
328 return routeBoundary;
329 } else {
330 return Boundary(-0.1, -0.1, 0.1, 0.1);
331 }
332}
333
334
335void
336GNERoute::splitEdgeGeometry(const double /*splitPosition*/, const GNENetworkElement* originalElement, const GNENetworkElement* newElement, GNEUndoList* undoList) {
337 // obtain new list of route edges
338 std::string newRouteEdges = getNewListOfParents(originalElement, newElement);
339 // update route edges
340 if (newRouteEdges.size() > 0) {
341 setAttribute(SUMO_ATTR_EDGES, newRouteEdges, undoList);
342 }
343}
344
345
346void
348 // Routes are drawn in drawPartialGL
349}
350
351
352void
355 // get parent vehicle
356 const GNEDemandElement* parentVehicle = getParentDemandElements().at(0);
357 // declare lane vector
358 std::vector<GNELane*> lanes;
359 // get first and last path lane
360 GNELane* firstLane = parentVehicle->getFirstPathLane();
361 GNELane* lastLane = parentVehicle->getLastPathLane();
362 // insert first vehicle lane
363 if (firstLane) {
364 lanes.push_back(firstLane);
365 }
366 // add middle lanes
367 for (int i = 1; i < ((int)getParentEdges().size() - 1); i++) {
368 lanes.push_back(getParentEdges().at(i)->getLaneByAllowedVClass(getVClass()));
369 }
370 // insert last vehicle lane
371 if (lastLane) {
372 lanes.push_back(lastLane);
373 }
374 // calculate consecutive path using vClass of vehicle parent
376 } else {
377 // calculate path using SVC_PASSENGER
379 // if path is empty, then calculate path again using SVC_IGNORING
380 if (!myNet->getPathManager()->isPathValid(this)) {
382 }
383 }
384}
385
386
387void
388GNERoute::drawPartialGL(const GUIVisualizationSettings& s, const GNELane* lane, const GNEPathManager::Segment* segment, const double offsetFront) const {
389 // get inspected and front flags
390 const bool dottedElement = myNet->getViewNet()->isAttributeCarrierInspected(this) ||
391 (myNet->getViewNet()->getFrontAttributeCarrier() == this) ||
392 myNet->getViewNet()->drawDeleteContour(this, this) ||
393 myNet->getViewNet()->drawSelectContour(this, this) ||
394 (gPostDrawing.markedRoute == this);
395 // check conditions
399 myNet->getPathManager()->getPathDraw()->drawPathGeometry(dottedElement, lane, myTagProperty.getTag())) {
400 // get embedded route flag
401 const bool embedded = (myTagProperty.getTag() == GNE_TAG_ROUTE_EMBEDDED);
402 // get route width
403 const double routeWidth = getExaggeration(s) * (embedded ? s.widthSettings.embeddedRouteWidth : s.widthSettings.routeWidth);
404 // calculate startPos
405 const double geometryDepartPos = embedded ? (getParentDemandElements().at(0)->getAttributeDouble(SUMO_ATTR_DEPARTPOS) + getParentDemandElements().at(0)->getParentDemandElements().at(0)->getAttributeDouble(SUMO_ATTR_LENGTH)) : -1;
406 // get endPos
407 const double geometryEndPos = embedded ? getParentDemandElements().at(0)->getAttributeDouble(SUMO_ATTR_ARRIVALPOS) : -1;
408 // declare path geometry
409 GUIGeometry routeGeometry;
410 // update pathGeometry depending of first and last segment
411 if (segment->isFirstSegment() && segment->isLastSegment()) {
412 routeGeometry.updateGeometry(lane->getLaneGeometry().getShape(),
413 geometryDepartPos, geometryEndPos, // extrem positions
414 Position::INVALID, Position::INVALID); // extra positions
415 } else if (segment->isFirstSegment()) {
416 routeGeometry.updateGeometry(lane->getLaneGeometry().getShape(),
417 geometryDepartPos, -1, // extrem positions
418 Position::INVALID, Position::INVALID); // extra positions
419 } else if (segment->isLastSegment()) {
420 routeGeometry.updateGeometry(lane->getLaneGeometry().getShape(),
421 -1, geometryEndPos, // extrem positions
422 Position::INVALID, Position::INVALID); // extra positions
423 } else {
424 routeGeometry = lane->getLaneGeometry();
425 }
426 // obtain color
428 // Start drawing adding an gl identificator
430 // Add a draw matrix
432 // Start with the drawing of the area traslating matrix to origin
433 myNet->getViewNet()->drawTranslateFrontAttributeCarrier(this, getType(), offsetFront + (embedded ? 0.1 : 0));
434 // Set color
435 GLHelper::setColor(routeColor);
436 // draw route geometry
437 GUIGeometry::drawGeometry(s, myNet->getViewNet()->getPositionInformation(), routeGeometry, routeWidth);
438 // Pop last matrix
440 // Draw name if isn't being drawn for selecting
442 drawName(getCenteringBoundary().getCenter(), s.scale, s.addName);
443 }
444 // Pop name
446 // check if we have to draw a red line to the next segment
447 if (segment->getNextSegment()) {
448 // push draw matrix
450 // Start with the drawing of the area traslating matrix to origin
452 // Set red color
454 // get firstPosition (last position of current lane shape)
455 const Position firstPosition = lane->getLaneShape().back();
456 // get lastPosition (first position of next lane shape)
457 const Position arrivalPos = segment->getNextSegment()->getPathElement()->getPathElementArrivalPos();
458 // draw box line
459 GLHelper::drawBoxLine(arrivalPos,
460 RAD2DEG(firstPosition.angleTo2D(arrivalPos)) - 90,
461 firstPosition.distanceTo2D(arrivalPos), .05);
462 // pop draw matrix
464 }
465 // check if mark this route
467 if ((gPostDrawing.markedRoute == nullptr) && myNet->getViewNet()->getViewParent()->getVehicleFrame()->shown() && templateAC &&
468 ((templateAC->getTagProperty().getTag() == SUMO_TAG_VEHICLE) || (templateAC->getTagProperty().getTag() == GNE_TAG_FLOW_ROUTE)) &&
469 (routeGeometry.getShape().distance2D(myNet->getViewNet()->getPositionInformation()) <= routeWidth)) {
471 }
472 // declare trim geometry to draw
473 const auto shape = (segment->isFirstSegment() || segment->isLastSegment() ? routeGeometry.getShape() : lane->getLaneShape());
474 // check if mouse is over element
475 mouseWithinGeometry(shape, routeWidth);
476 // inspect contour
479 }
480 // front contour
481 if (myNet->getViewNet()->getFrontAttributeCarrier() == this) {
483 }
484 // delete contour
485 if (myNet->getViewNet()->drawDeleteContour(this, this)) {
487 }
488 // select contour
489 if (myNet->getViewNet()->drawSelectContour(this, this)) {
491 }
492 // draw marked dotted contour
493 if (gPostDrawing.markedRoute == this) {
495 }
496 }
497}
498
499
500void
501GNERoute::drawPartialGL(const GUIVisualizationSettings& s, const GNELane* fromLane, const GNELane* toLane, const GNEPathManager::Segment* /*segment*/, const double offsetFront) const {
502 // get inspected and front flags
503 const bool dottedElement = myNet->getViewNet()->isAttributeCarrierInspected(this) ||
504 (myNet->getViewNet()->getFrontAttributeCarrier() == this) ||
505 myNet->getViewNet()->drawDeleteContour(this, this) ||
506 myNet->getViewNet()->drawSelectContour(this, this) ||
507 (gPostDrawing.markedRoute == this);
508 // check conditions
511 fromLane->getLane2laneConnections().exist(toLane) &&
513 myNet->getPathManager()->getPathDraw()->drawPathGeometry(dottedElement, fromLane, toLane, myTagProperty.getTag())) {
514 // get embedded route flag
515 const bool embedded = (myTagProperty.getTag() == GNE_TAG_ROUTE_EMBEDDED);
516 // get route width
517 const double routeWidth = getExaggeration(s) * (embedded ? s.widthSettings.embeddedRouteWidth : s.widthSettings.routeWidth);
518 // obtain lane2lane geometry
519 const GUIGeometry& lane2laneGeometry = fromLane->getLane2laneConnections().getLane2laneGeometry(toLane);
520 // obtain color
522 // Start drawing adding an gl identificator
524 // Add a draw matrix
526 // Start with the drawing of the area traslating matrix to origin
527 myNet->getViewNet()->drawTranslateFrontAttributeCarrier(this, getType(), offsetFront + (embedded ? 0.1 : 0));
528 // Set color
529 GLHelper::setColor(routeColor);
530 // draw lane2lane
531 GUIGeometry::drawGeometry(s, myNet->getViewNet()->getPositionInformation(), lane2laneGeometry, routeWidth);
532 // Pop last matrix
534 // Pop name
536 // draw lock icon
538 // check if mark this route
540 if ((gPostDrawing.markedRoute == nullptr) && myNet->getViewNet()->getViewParent()->getVehicleFrame()->shown() && templateAC &&
541 ((templateAC->getTagProperty().getTag() == SUMO_TAG_VEHICLE) || (templateAC->getTagProperty().getTag() == GNE_TAG_FLOW_ROUTE)) &&
542 (lane2laneGeometry.getShape().distance2D(myNet->getViewNet()->getPositionInformation()) <= routeWidth)) {
544 }
545 // check if mouse is over element
547 // inspect contour
550 routeWidth, 1, false, false);
551 }
552 // front contour
553 if (myNet->getViewNet()->getFrontAttributeCarrier() == this) {
555 routeWidth, 1, false, false);
556 }
557 // delete contour
558 if (myNet->getViewNet()->drawDeleteContour(this, this)) {
560 routeWidth, 1, false, false);
561 }
562 // select contour
563 if (myNet->getViewNet()->drawSelectContour(this, this)) {
565 routeWidth, 1, false, false);
566 }
567 // green contour
568 if (gPostDrawing.markedRoute == this) {
570 routeWidth, 1, false, false);
571 }
572 }
573}
574
575
576GNELane*
579 return getParentEdges().front()->getLaneByAllowedVClass(SVC_PASSENGER);
580 } else {
581 return getParentDemandElements().at(0)->getFirstPathLane();
582 }
583}
584
585
586GNELane*
589 return getParentEdges().back()->getLaneByAllowedVClass(SVC_PASSENGER);
590 } else {
591 return getParentDemandElements().at(0)->getLastPathLane();
592 }
593}
594
595
596std::string
598 switch (key) {
599 case SUMO_ATTR_ID:
600 return getMicrosimID();
601 case SUMO_ATTR_EDGES:
602 return parseIDs(getParentEdges());
603 case SUMO_ATTR_COLOR:
605 return toString(myColor);
606 } else {
607 return "";
608 }
609 case SUMO_ATTR_REPEAT:
610 return toString(myRepeat);
612 return time2string(myCycleTime);
616 return getParametersStr();
617 default:
618 throw InvalidArgument(getTagStr() + " doesn't have an attribute of type '" + toString(key) + "'");
619 }
620}
621
622
623double
625 switch (key) {
627 return 0;
629 return getParentEdges().back()->getLanes().front()->getLaneShape().length2D();
630 default:
631 throw InvalidArgument(getTagStr() + " doesn't have an attribute of type '" + toString(key) + "'");
632 }
633}
634
635
638 switch (key) {
640 return getParentEdges().front()->getLanes().front()->getLaneShape().front();
642 return getParentEdges().back()->getLanes().front()->getLaneShape().back();
643 default:
644 throw InvalidArgument(getTagStr() + " doesn't have an attribute of type '" + toString(key) + "'");
645 }
646}
647
648
649void
650GNERoute::setAttribute(SumoXMLAttr key, const std::string& value, GNEUndoList* undoList) {
651 if (value == getAttribute(key)) {
652 return; //avoid needless changes, later logic relies on the fact that attributes have changed
653 }
654 switch (key) {
655 case SUMO_ATTR_ID:
656 case SUMO_ATTR_COLOR:
657 case SUMO_ATTR_REPEAT:
661 undoList->changeAttribute(new GNEChange_Attribute(this, key, value));
662 break;
663 // special case due depart and arrival edge vehicles
664 case SUMO_ATTR_EDGES: {
665 // extract all vehicle childrens
666 std::vector<GNEDemandElement*> vehicles;
667 for (const auto& childDemandElement : getChildDemandElements()) {
668 if (childDemandElement->getTagProperty().isVehicle()) {
669 vehicles.push_back(childDemandElement);
670 }
671 }
672 // check vehicles
673 if (vehicles.size() > 0) {
674 undoList->begin(GUIIcon::ROUTE, "reset start and end edges");
675 for (const auto& vehicle : vehicles) {
676 undoList->changeAttribute(new GNEChange_Attribute(vehicle, SUMO_ATTR_DEPARTEDGE, ""));
677 undoList->changeAttribute(new GNEChange_Attribute(vehicle, SUMO_ATTR_ARRIVALEDGE, ""));
678 }
679 undoList->changeAttribute(new GNEChange_Attribute(this, key, value));
680 undoList->end();
682 undoList->begin(GUIIcon::ROUTE, "reset start and end edges");
685 undoList->changeAttribute(new GNEChange_Attribute(this, key, value));
686 undoList->end();
687 } else {
688 // just change edges
689 undoList->changeAttribute(new GNEChange_Attribute(this, key, value));
690 }
691 break;
692 }
693 default:
694 throw InvalidArgument(getTagStr() + " doesn't have an attribute of type '" + toString(key) + "'");
695 }
696}
697
698
699bool
700GNERoute::isValid(SumoXMLAttr key, const std::string& value) {
701 switch (key) {
702 case SUMO_ATTR_ID:
703 return isValidDemandElementID(value);
704 case SUMO_ATTR_EDGES:
705 if (canParse<std::vector<GNEEdge*> >(myNet, value, false)) {
706 // all edges exist, then check if compounds a valid route
707 return isRouteValid(parse<std::vector<GNEEdge*> >(myNet, value)).empty();
708 } else {
709 return false;
710 }
711 case SUMO_ATTR_COLOR:
712 if (value.empty()) {
713 return true;
714 } else {
715 return canParse<RGBColor>(value);
716 }
717 case SUMO_ATTR_REPEAT:
718 return canParse<int>(value);
720 if (canParse<SUMOTime>(value)) {
721 return (parse<SUMOTime>(value) >= 0);
722 } else {
723 return false;
724 }
726 return canParse<bool>(value);
729 default:
730 throw InvalidArgument(getTagStr() + " doesn't have an attribute of type '" + toString(key) + "'");
731 }
732}
733
734
735std::string
737 return getTagStr();
738}
739
740
741std::string
743 return getTagStr() + ": " + getAttribute(SUMO_ATTR_ID) ;
744}
745
746
749 return getParametersMap();
750}
751
752
753std::string
754GNERoute::isRouteValid(const std::vector<GNEEdge*>& edges) {
755 if (edges.size() == 0) {
756 // routes cannot be empty
757 return ("list of route edges cannot be empty");
758 } else if (edges.size() == 1) {
759 // routes with a single edge are valid, then return an empty string
760 return ("");
761 } else {
762 // iterate over edges to check that compounds a chain
763 auto it = edges.begin();
764 while (it != edges.end() - 1) {
765 const GNEEdge* currentEdge = *it;
766 const GNEEdge* nextEdge = *(it + 1);
767 // same consecutive edges aren't allowed
768 if (currentEdge->getID() == nextEdge->getID()) {
769 return ("consecutive duplicated edges (" + currentEdge->getID() + ") aren't allowed in a route");
770 }
771 // obtain outgoing edges of currentEdge
772 const std::vector<GNEEdge*>& outgoingEdges = currentEdge->getToJunction()->getGNEOutgoingEdges();
773 // check if nextEdge is in outgoingEdges
774 if (std::find(outgoingEdges.begin(), outgoingEdges.end(), nextEdge) == outgoingEdges.end()) {
775 return ("Edges '" + currentEdge->getID() + "' and '" + nextEdge->getID() + "' aren't consecutives");
776 }
777 it++;
778 }
779 // all edges consecutives, then return an empty string
780 return ("");
781 }
782}
783
784// ===========================================================================
785// private
786// ===========================================================================
787
788void
789GNERoute::setAttribute(SumoXMLAttr key, const std::string& value) {
790 switch (key) {
791 case SUMO_ATTR_ID:
792 // update microsimID
793 setMicrosimID(value);
794 break;
795 case SUMO_ATTR_EDGES:
797 // compute route
799 break;
800 case SUMO_ATTR_COLOR:
801 if (value.empty()) {
803 } else {
804 myColor = parse<RGBColor>(value);
805 }
806 break;
807 case SUMO_ATTR_REPEAT:
808 myRepeat = parse<int>(value);
809 break;
811 myCycleTime = string2time(value);
812 break;
814 if (parse<bool>(value)) {
816 } else {
818 }
819 break;
821 setParametersStr(value);
822 break;
823 default:
824 throw InvalidArgument(getTagStr() + " doesn't have an attribute of type '" + toString(key) + "'");
825 }
826}
827
828
829void
830GNERoute::setMoveShape(const GNEMoveResult& /*moveResult*/) {
831 // routes cannot be moved
832}
833
834
835void
836GNERoute::commitMoveShape(const GNEMoveResult& /*moveResult*/, GNEUndoList* /*undoList*/) {
837 // routes cannot be moved
838}
839
840/****************************************************************************/
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:460
@ MID_COPY_NAME
Copy object name - popup entry.
Definition: GUIAppEnum.h:448
@ MID_GNE_ROUTE_APPLY_DISTANCE
apply distance
Definition: GUIAppEnum.h:1281
@ 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
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
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 (used in NETEDIT)
@ 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: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
virtual GNELane * getLastPathLane() const =0
get last path lane
virtual GNELane * getFirstPathLane() const =0
get first path lane
std::vector< const GNEDemandElement * > getSortedStops(const std::vector< GNEEdge * > &edges) const
get sorted stops
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:142
const GNELane2laneConnection & getLane2laneConnections() const
get Lane2laneConnection struct
Definition: GNELane.cpp:917
Position getPositionInView() const
Returns position of hierarchical element in view.
Definition: GNELane.cpp:241
const GUIGeometry & getLaneGeometry() const
Definition: GNELane.cpp:136
move operation
move result
A NBNetBuilder extended by visualisation and editing capabilities.
Definition: GNENet.h:42
GNEPathManager * getPathManager()
get path manager
Definition: GNENet.cpp:138
GNEViewNet * getViewNet() const
get view net
Definition: GNENet.cpp:1987
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:742
void fixDemandElementProblem()
fix demand element problem (by default throw an exception, has to be reimplemented in children)
Definition: GNERoute.cpp:263
double getExaggeration(const GUIVisualizationSettings &s) const
return exaggeration associated with this GLObject
Definition: GNERoute.cpp:314
GNELane * getLastPathLane() const
get last path lane
Definition: GNERoute.cpp:587
Position getPositionInView() const
Returns position of additional in view.
Definition: GNERoute.cpp:302
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:308
SUMOTime myCycleTime
cycleTime
Definition: GNERoute.h:267
std::string getPopUpID() const
get PopPup ID (Used in AC Hierarchy)
Definition: GNERoute.cpp:736
std::string getAttribute(SumoXMLAttr key) const
inherited from GNEAttributeCarrier
Definition: GNERoute.cpp:597
Position getAttributePosition(SumoXMLAttr key) const
Definition: GNERoute.cpp:637
void updateGeometry()
update pre-computed geometry information
Definition: GNERoute.cpp:289
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:336
void setMoveShape(const GNEMoveResult &moveResult)
set move shape
Definition: GNERoute.cpp:830
const Parameterised::Map & getACParametersMap() const
get parameters map
Definition: GNERoute.cpp:748
GNELane * getFirstPathLane() const
get first path lane
Definition: GNERoute.cpp:577
double getAttributeDouble(SumoXMLAttr key) const
Definition: GNERoute.cpp:624
GNEMoveOperation * getMoveOperation()
get move operation
Definition: GNERoute.cpp:149
void commitMoveShape(const GNEMoveResult &moveResult, GNEUndoList *undoList)
commit move shape
Definition: GNERoute.cpp:836
SUMOVehicleClass getVClass() const
Definition: GNERoute.cpp:269
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:388
Boundary getCenteringBoundary() const
Returns the boundary to which the view shall be centered in order to show the object.
Definition: GNERoute.cpp:320
bool isValid(SumoXMLAttr key, const std::string &value)
method for checking if the key and their conrrespond attribute are valids
Definition: GNERoute.cpp:700
void drawGL(const GUIVisualizationSettings &s) const
Draws the object.
Definition: GNERoute.cpp:347
static std::string isRouteValid(const std::vector< GNEEdge * > &edges)
check if a route is valid
Definition: GNERoute.cpp:754
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:650
int myRepeat
repeat
Definition: GNERoute.h:264
void computePathElement()
compute pathElement
Definition: GNERoute.cpp:353
std::string getDemandElementProblem() const
return a string with the current demand element problem (by default empty, can be reimplemented in ch...
Definition: GNERoute.cpp:245
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:275
Problem isDemandElementValid() const
check if current demand element is valid to be writed into XML (by default true, can be reimplemented...
Definition: GNERoute.cpp:215
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
Definition: GNEViewNet.cpp:656
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
Definition: GNEViewNet.cpp:644
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.
Definition: GNEViewNet.cpp:474
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:650
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
Definition: GUIDesigns.cpp:42
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
Definition: GUIGeometry.cpp:58
const std::string & getMicrosimID() const
Returns the id of the object as known to microsim.
Definition: GUIGlObject.h:141
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 mouseWithinGeometry(const Position center, const double radius) const
check if mouse is within elements geometry (for circles)
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.
Definition: GUIGlObject.h:154
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.
Definition: GUIGlObject.h:102
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.
Definition: OutputDevice.h:61
OutputDevice & writeAttr(const SumoXMLAttr attr, const T &val)
writes a named attribute
Definition: OutputDevice.h:251
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.
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|....
std::map< std::string, std::string > Map
parameters map
Definition: Parameterised.h:45
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:298
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
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)
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