Eclipse SUMO - Simulation of Urban MObility
Loading...
Searching...
No Matches
GNEDemandElement.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 abstract class for demand elements
19/****************************************************************************/
20#include <config.h>
21
22#include <netedit/GNENet.h>
23#include <netedit/GNEViewNet.h>
32
33#include "GNEDemandElement.h"
34
35
36// ===========================================================================
37// static definitions
38// ===========================================================================
40
41// ===========================================================================
42// member method definitions
43// ===========================================================================
44
45// ---------------------------------------------------------------------------
46// GNEDemandElement - methods
47// ---------------------------------------------------------------------------
48
49GNEDemandElement::GNEDemandElement(const std::string& id, GNENet* net, GUIGlObjectType type, SumoXMLTag tag, FXIcon* icon, const int options,
50 const std::vector<GNEJunction*>& junctionParents,
51 const std::vector<GNEEdge*>& edgeParents,
52 const std::vector<GNELane*>& laneParents,
53 const std::vector<GNEAdditional*>& additionalParents,
54 const std::vector<GNEDemandElement*>& demandElementParents,
55 const std::vector<GNEGenericData*>& genericDataParents) :
56 GNEPathManager::PathElement(type, id, icon, options),
57 GNEHierarchicalElement(net, tag, junctionParents, edgeParents, laneParents, additionalParents, demandElementParents, genericDataParents),
58 myStackedLabelNumber(0) {
59 // check if is template
60 myIsTemplate = (id == "");
61}
62
63
64GNEDemandElement::GNEDemandElement(GNEDemandElement* demandElementParent, GNENet* net, GUIGlObjectType type, SumoXMLTag tag, FXIcon* icon, const int options,
65 const std::vector<GNEJunction*>& junctionParents,
66 const std::vector<GNEEdge*>& edgeParents,
67 const std::vector<GNELane*>& laneParents,
68 const std::vector<GNEAdditional*>& additionalParents,
69 const std::vector<GNEDemandElement*>& demandElementParents,
70 const std::vector<GNEGenericData*>& genericDataParents) :
71 GNEPathManager::PathElement(type, demandElementParent->getID(), icon, options),
72 GNEHierarchicalElement(net, tag, junctionParents, edgeParents, laneParents, additionalParents, demandElementParents, genericDataParents),
73 myStackedLabelNumber(0) {
74}
75
76
78
79
80void
81GNEDemandElement::removeGeometryPoint(const Position /*clickedPosition*/, GNEUndoList* /*undoList*/) {
82 // currently there isn't demand elements with removable geometry points
83}
84
85
88 return this;
89}
90
91
92const GUIGeometry&
96
97
100 // first check if there are demand elements
101 if (getChildDemandElements().empty()) {
102 return nullptr;
103 } else {
104 // find child demand element
105 auto it = std::find(getChildDemandElements().begin(), getChildDemandElements().end(), demandElement);
106 // return element or null depending of iterator
107 if (it == getChildDemandElements().end()) {
108 // in this case, we assume that the last child is the previos child
109 return getChildDemandElements().back();
110 } else if (it == getChildDemandElements().begin()) {
111 return nullptr;
112 } else {
113 return *(it - 1);
114 }
115 }
116}
117
118
121 // find child demand element
122 auto it = std::find(getChildDemandElements().begin(), getChildDemandElements().end(), demandElement);
123 // return element or null depending of iterator
124 if (it == getChildDemandElements().end()) {
125 return nullptr;
126 } else if (it == (getChildDemandElements().end() - 1)) {
127 return nullptr;
128 } else {
129 return *(it + 1);
130 }
131}
132
133
134void
138
139
140void
144
145
146void
150
151
152void
154 throw InvalidArgument(getTagStr() + " doesn't have a demand element dialog");
155}
156
157
158std::string
160 throw InvalidArgument(getTagStr() + " doesn't have a begin time");
161}
162
163
166 GUIGLObjectPopupMenu* ret = new GUIGLObjectPopupMenu(app, parent, *this);
167 // build header
168 buildPopupHeader(ret, app);
169 // build menu command for center button and copy cursor position to clipboard
171 buildPositionCopyEntry(ret, app);
172 // buld menu commands for names
173 GUIDesigns::buildFXMenuCommand(ret, "Copy " + getTagStr() + " name to clipboard", nullptr, ret, MID_COPY_NAME);
174 GUIDesigns::buildFXMenuCommand(ret, "Copy " + getTagStr() + " typed name to clipboard", nullptr, ret, MID_COPY_TYPED_NAME);
175 new FXMenuSeparator(ret);
176 // build selection and show parameters menu
179 // show option to open demand element dialog
180 if (myTagProperty.hasDialog()) {
181 GUIDesigns::buildFXMenuCommand(ret, ("Open " + getTagStr() + " Dialog").c_str(), getACIcon(), &parent, MID_OPEN_ADDITIONAL_DIALOG);
182 new FXMenuSeparator(ret);
183 }
184 GUIDesigns::buildFXMenuCommand(ret, "Cursor position in view: " + toString(getPositionInView().x()) + "," + toString(getPositionInView().y()), nullptr, nullptr, 0);
185 return ret;
186}
187
188
191 // Create table
193 // Iterate over attributes
194 for (const auto& i : myTagProperty) {
195 // Add attribute and set it dynamic if aren't unique
196 if (i.isUnique()) {
197 ret->mkItem(i.getAttrStr().c_str(), false, getAttribute(i.getAttr()));
198 } else {
199 ret->mkItem(i.getAttrStr().c_str(), true, getAttribute(i.getAttr()));
200 }
201 }
202 // close building
203 ret->closeBuilding();
204 return ret;
205}
206
207
208bool
216
217
218void
222
223
224void
226 // we need an special checks due hierarchies
228 // get person/container plarent
229 GNEDemandElement* parent = getParentDemandElements().front();
230 // if this is the last person/container plan element, remove parent instead plan
231 if (parent->getChildDemandElements().size() == 1) {
232 parent->deleteGLObject();
233 } else {
235 }
236 } else if (getTagProperty().getTag() == GNE_TAG_ROUTE_EMBEDDED) {
237 // remove parent demand element
238 getParentDemandElements().front()->deleteGLObject();
239 } else {
241 }
242}
243
244
245void
255
256
257void
261
262
263bool
267
268
269double
271 // get previous person Plan
272 const GNEDemandElement* previousPersonPlan = getParentDemandElements().at(0)->getPreviousChildDemandElement(this);
273 // check if this is the first person plan
274 if (previousPersonPlan) {
275 if (previousPersonPlan->getParentAdditionals().size() > 0) {
276 if (previousPersonPlan->getTagProperty().isStopPerson()) {
277 // calculate busStop end
278 const double endPos = previousPersonPlan->getParentAdditionals().front()->getAttributeDouble(SUMO_ATTR_ENDPOS);
279 // check endPos
280 if (endPos < 0.3) {
281 return endPos;
282 } else {
283 return (endPos - 0.3);
284 }
285 } else {
286 // use busStop center
287 return previousPersonPlan->getParentAdditionals().front()->getAttributeDouble(SUMO_ATTR_CENTER);
288 }
289 } else {
290 // use arrival pos
291 return previousPersonPlan->getAttributeDouble(SUMO_ATTR_ARRIVALPOS);
292 }
293 } else {
294 // use pedestrian departPos
295 return getParentDemandElements().at(0)->getAttributeDouble(SUMO_ATTR_DEPARTPOS);
296 }
297}
298
299
302 // get previous person Plan
303 const GNEDemandElement* previousPersonPlan = getParentDemandElements().at(0)->getPreviousChildDemandElement(this);
304 // check if this is the first person plan
305 if (previousPersonPlan) {
306 if (previousPersonPlan->getParentAdditionals().size() > 0) {
307 if (previousPersonPlan->getTagProperty().isStopPerson()) {
308 // get busStop
309 const GNEAdditional* busStop = previousPersonPlan->getParentAdditionals().front();
310 // get length
311 const double length = busStop->getAdditionalGeometry().getShape().length2D();
312 // check length
313 if (length < 0.3) {
314 return busStop->getAdditionalGeometry().getShape().back();
315 } else {
316 return busStop->getAdditionalGeometry().getShape().positionAtOffset2D(length - 0.3);
317 }
318 } else {
319 // use busStop center
320 return previousPersonPlan->getParentAdditionals().front()->getAdditionalGeometry().getShape().getLineCenter();
321 }
322 } else {
323 // use arrival pos
324 return previousPersonPlan->getAttributePosition(SUMO_ATTR_ARRIVALPOS);
325 }
326 } else if (getParentJunctions().size() > 0) {
327 return getParentJunctions().front()->getNBNode()->getPosition();
328 } else {
329 // use pedestrian departPos
330 return getParentDemandElements().at(0)->getAttributePosition(SUMO_ATTR_DEPARTPOS);
331 }
332}
333
334
335double
337 // check if this person plan ends in a busStop
338 if (getParentAdditionals().size() > 0) {
339 // get next person Plan
340 const GNEDemandElement* nextPersonPlan = getParentDemandElements().at(0)->getNextChildDemandElement(this);
341 // continue depending if is an stop or a person plan
342 if (nextPersonPlan && ((nextPersonPlan->getTagProperty().getTag() == GNE_TAG_STOPPERSON_BUSSTOP) || (nextPersonPlan->getTagProperty().getTag() == GNE_TAG_STOPPERSON_TRAINSTOP))) {
343 // calculate busStop end
344 const double endPos = getParentAdditionals().front()->getAttributeDouble(SUMO_ATTR_ENDPOS);
345 // check endPos
346 if (endPos < 0.3) {
347 return getParentAdditionals().front()->getAttributeDouble(SUMO_ATTR_ENDPOS);
348 } else {
349 return getParentAdditionals().front()->getAttributeDouble(SUMO_ATTR_ENDPOS) - 0.3;
350 }
351 } else {
352 return getParentAdditionals().front()->getAttributeDouble(SUMO_ATTR_CENTER);
353 }
354 } else {
356 }
357}
358
359
362 // check if this person plan ends in a busStop
363 if (getParentAdditionals().size() > 0) {
364 // get next person Plan
365 const GNEDemandElement* nextPersonPlan = getParentDemandElements().at(0)->getNextChildDemandElement(this);
366 // continue depending if is an stop or a person plan
367 if (nextPersonPlan && ((nextPersonPlan->getTagProperty().getTag() == GNE_TAG_STOPPERSON_BUSSTOP) || (nextPersonPlan->getTagProperty().getTag() == GNE_TAG_STOPPERSON_TRAINSTOP))) {
368 // get busStop
369 const GNEAdditional* busStop = nextPersonPlan->getParentAdditionals().front();
370 // get length
371 const double length = busStop->getAdditionalGeometry().getShape().length2D();
372 // check length
373 if (length < 0.3) {
374 return busStop->getAdditionalGeometry().getShape().back();
375 } else {
376 return busStop->getAdditionalGeometry().getShape().positionAtOffset2D(length - 0.3);
377 }
378 } else {
379 return getParentAdditionals().front()->getAdditionalGeometry().getShape().getLineCenter();
380 }
381 } else if (getParentJunctions().size() > 0) {
382 return getParentJunctions().back()->getNBNode()->getPosition();
383 } else {
385 }
386}
387
388// ---------------------------------------------------------------------------
389// GNEDemandElement - protected methods
390// ---------------------------------------------------------------------------
391
392bool
393GNEDemandElement::isValidDemandElementID(const std::string& newID) const {
395 return true;
396 } else {
397 return false;
398 }
399}
400
401
404 if (getParentDemandElements().size() < 1) {
405 throw InvalidArgument("This demand element doesn't have a type parent");
406 } else if (!getParentDemandElements().at(0)->getTagProperty().isType()) {
407 throw InvalidArgument("The first parent isn't a type");
408 } else if (getParentDemandElements().at(0)->getTagProperty().getTag() == SUMO_TAG_VTYPE) {
409 return getParentDemandElements().at(0);
410 } else {
411 // get typeDistribution ID
412 const auto typeDistributionID = getParentDemandElements().at(0)->getID();
413 // obtain all types with the given typeDistribution sorted by ID
414 std::map<std::string, GNEDemandElement*> sortedTypes;
415 for (const auto &type : myNet->getAttributeCarriers()->getDemandElements().at(SUMO_TAG_VTYPE)) {
416 if (type->getAttribute(GNE_ATTR_VTYPE_DISTRIBUTION) == typeDistributionID) {
417 sortedTypes[type->getID()] = type;
418 }
419 }
420 // return first type, or default vType
421 if (sortedTypes.size() > 0) {
422 return sortedTypes.begin()->second;
423 } else if (myNet->getAttributeCarriers()->getDemandElements().size() > 0){
425 } else {
426 throw InvalidArgument("no vTypes");
427 }
428 }
429}
430
431
434 if (getParentDemandElements().size() < 2) {
435 throw InvalidArgument("This demand element doesn't have two parent");
436 } else if (getParentDemandElements().at(1)->getTagProperty().getTag() != SUMO_TAG_ROUTE) {
437 throw InvalidArgument("This demand element doesn't have a route parent");
438 } else {
439 return getParentDemandElements().at(1);
440 }
441}
442
443
444const Position
445GNEDemandElement::getBeginPosition(const double pedestrianDepartPos) const {
447 return getPositionInView();
448 } else {
449 // get first lane
450 const GNELane* firstLane = myNet->getPathManager()->getFirstLane(this);
451 if (firstLane) {
452 return firstLane->getLaneShape().positionAtOffset2D(pedestrianDepartPos);
453 } else {
454 return Position(0, 0);
455 }
456 }
457}
458
459
460std::vector<GNEDemandElement*>
463 // get stops
464 std::vector<GNEDemandElement*> invalidStops;
465 // get edge stop index
466 const auto edgeStopIndex = getEdgeStopIndex();
467 // take all stops/waypoints with index = -1
468 for (const auto& edgeStop : edgeStopIndex) {
469 if (edgeStop.stopIndex == -1) {
470 for (const auto& stop : edgeStop.stops) {
471 invalidStops.push_back(stop);
472 }
473 }
474 }
475 return invalidStops;
476 } else {
477 return {};
478 }
479}
480
481
482bool
484 // check conditions
488 // show all person plans in network mode
489 return true;
492 // show all person plans
493 return true;
495 // show selected
496 return true;
498 // person parent is inspected
499 return true;
501 // person parent is locked
502 return true;
503 } else if (myNet->getViewNet()->getInspectedAttributeCarriers().empty()) {
504 // nothing is inspected
505 return false;
506 } else {
507 // get inspected AC
509 // check condition
511 // common person parent
512 return true;
513 } else {
514 // all conditions are false
515 return false;
516 }
517 }
518}
519
520
521bool
523 // check conditions
527 // show all container plans in network mode
528 return true;
531 // show all container plans
532 return true;
534 // show selected
535 return true;
537 // container parent is inspected
538 return true;
540 // container parent is locked
541 return true;
542 } else if (myNet->getViewNet()->getInspectedAttributeCarriers().empty()) {
543 // nothing is inspected
544 return false;
545 } else {
546 // get inspected AC
548 // check condition
550 // common container parent
551 return true;
552 } else {
553 // all conditions are false
554 return false;
555 }
556 }
557}
558
559
560void
562 const double offsetFront, const double personPlanWidth, const RGBColor& personPlanColor) const {
563 // get inspected and front flags
564 const bool dottedElement = myNet->getViewNet()->isAttributeCarrierInspected(this) || (myNet->getViewNet()->getFrontAttributeCarrier() == this);
565 // get person parent
566 const GNEDemandElement* personParent = getParentDemandElements().front();
567 // check if draw person plan element can be drawn
568 if ((personPlanColor.alpha() != 0) && drawPlan && myNet->getPathManager()->getPathDraw()->drawPathGeometry(dottedElement, lane, myTagProperty.getTag())) {
569 // get inspected attribute carriers
570 const auto& inspectedACs = myNet->getViewNet()->getInspectedAttributeCarriers();
571 // get inspected person plan
572 const GNEAttributeCarrier* personPlanInspected = (inspectedACs.size() > 0) ? inspectedACs.front() : nullptr;
573 // flag to check if width must be duplicated
574 const bool duplicateWidth = (personPlanInspected == this) || (personPlanInspected == personParent);
575 // calculate path width
576 const double pathWidth = s.addSize.getExaggeration(s, lane) * personPlanWidth * (duplicateWidth ? 2 : 1);
577 // declare path geometry
578 GUIGeometry personPlanGeometry;
579 // update pathGeometry depending of first and last segment
580 if (segment->isFirstSegment() && segment->isLastSegment()) {
581 personPlanGeometry.updateGeometry(lane->getLaneGeometry().getShape(),
583 getPathElementDepartPos(), getPathElementArrivalPos()); // extra positions
584 } else if (segment->isFirstSegment()) {
585 personPlanGeometry.updateGeometry(lane->getLaneGeometry().getShape(),
586 getPathElementDepartValue(), -1, // extrem positions
587 getPathElementDepartPos(), Position::INVALID); // extra positions
588 } else if (segment->isLastSegment()) {
589 personPlanGeometry.updateGeometry(lane->getLaneGeometry().getShape(),
590 -1, getPathElementArrivalValue(), // extrem positions
591 Position::INVALID, getPathElementArrivalPos()); // extra positions
592 } else {
593 personPlanGeometry = lane->getLaneGeometry();
594 }
595 // get color
596 const RGBColor& pathColor = drawUsingSelectColor() ? s.colorSettings.selectedPersonPlanColor : personPlanColor;
597 // Start drawing adding an gl identificator
599 // Add a draw matrix
601 // Start with the drawing of the area traslating matrix to origin
603 // Set color
604 GLHelper::setColor(pathColor);
605 // draw geometry
606 GUIGeometry::drawGeometry(s, myNet->getViewNet()->getPositionInformation(), personPlanGeometry, pathWidth);
607 // Pop last matrix
609 // Draw name if isn't being drawn for selecting
611 drawName(getCenteringBoundary().getCenter(), s.scale, s.addName);
612 }
613 // check if this is the last segment
614 if (segment->isLastSegment()) {
615 // calculate circle width
616 const double circleRadius = (duplicateWidth ? myPersonPlanArrivalPositionDiameter : (myPersonPlanArrivalPositionDiameter / 2.0));
617 const double circleWidth = circleRadius * MIN2((double)0.5, s.laneWidthExaggeration);
618 const double circleWidthSquared = circleWidth * circleWidth;
619 // get geometryEndPos
620 const Position geometryEndPos = getPathElementArrivalPos();
621 // check if endPos can be drawn
622 if (!s.drawForRectangleSelection || (myNet->getViewNet()->getPositionInformation().distanceSquaredTo2D(geometryEndPos) <= (circleWidthSquared + 2))) {
623 // push draw matrix
625 // Start with the drawing of the area traslating matrix to origin
627 // translate to pos and move to upper using GLO_PERSONTRIP (to avoid overlapping)
628 glTranslated(geometryEndPos.x(), geometryEndPos.y(), 0);
629 // Set person plan color
630 GLHelper::setColor(pathColor);
631 // resolution of drawn circle depending of the zoom (To improve smothness)
633 // pop draw matrix
635 }
636 }
637 // check if we have to draw an red arrow or line
638 if (segment->getNextSegment() && segment->getNextSegment()->getLane()) {
639 // get firstPosition (last position of current lane shape)
640 const Position from = lane->getLaneShape().back();
641 // get lastPosition (first position of next lane shape)
642 const Position to = segment->getNextSegment()->getLane()->getLaneShape().front();
643 // push draw matrix
645 // Start with the drawing of the area traslating matrix to origin
647 // draw child line
648 GUIGeometry::drawChildLine(s, from, to, RGBColor::RED, dottedElement || isAttributeCarrierSelected(), .05);
649 // pop draw matrix
651 }
652 // check if we have to draw an red arrow or line
653 if (segment->getPreviousSegment() && segment->getPreviousSegment()->getLane()) {
654 // get firstPosition (last position of current lane shape)
655 const Position from = lane->getLaneShape().front();
656 // get lastPosition (first position of next lane shape)
657 const Position to = segment->getPreviousSegment()->getLane()->getLaneShape().back();
658 // push draw matrix
660 // Start with the drawing of the area traslating matrix to origin
662 // draw child line
663 GUIGeometry::drawChildLine(s, from, to, RGBColor::RED, dottedElement || isAttributeCarrierSelected(), .05);
664 // pop draw matrix
666 }
667 // Pop name
669 // declare trim geometry to draw
670 const auto shape = (segment->isFirstSegment() || segment->isLastSegment()) ? personPlanGeometry.getShape() : lane->getLaneShape();
671 // check if mouse is over element
672 mouseWithinGeometry(shape, pathWidth);
673 // check if shape dotted contour has to be drawn
674 if (dottedElement) {
675 // inspect contour
678 }
679 // front element contour
680 if (myNet->getViewNet()->getFrontAttributeCarrier() == this) {
682 }
683 // delete contour
684 if (myNet->getViewNet()->drawDeleteContour(this, this)) {
686 }
687 // select contour
688 if (myNet->getViewNet()->drawSelectContour(this, this)) {
690 }
691 }
692 }
693 // draw person parent if this is the edge first edge and this is the first plan
694 if (getParentJunctions().empty() && (getFirstPathLane()->getParentEdge() == lane->getParentEdge()) &&
695 (personParent->getChildDemandElements().front() == this)) {
696 personParent->drawGL(s);
697 }
698}
699
700
701void
702GNEDemandElement::drawPersonPlanPartial(const bool drawPlan, const GUIVisualizationSettings& s, const GNELane* fromLane, const GNELane* toLane, const GNEPathManager::Segment* /*segment*/,
703 const double offsetFront, const double personPlanWidth, const RGBColor& personPlanColor) const {
704 // get inspected and front flags
705 const bool dottedElement = myNet->getViewNet()->isAttributeCarrierInspected(this) || (myNet->getViewNet()->getFrontAttributeCarrier() == this);
706 // check if draw person plan elements can be drawn
707 if ((personPlanColor.alpha() != 0) && drawPlan && myNet->getPathManager()->getPathDraw()->drawPathGeometry(false, fromLane, toLane, myTagProperty.getTag())) {
708 // get inspected attribute carriers
709 const auto& inspectedACs = myNet->getViewNet()->getInspectedAttributeCarriers();
710 // get person parent
711 const GNEDemandElement* personParent = getParentDemandElements().front();
712 // get inspected person plan
713 const GNEAttributeCarrier* personPlanInspected = (inspectedACs.size() > 0) ? inspectedACs.front() : nullptr;
714 // flag to check if width must be duplicated
715 const bool duplicateWidth = (personPlanInspected == this) || (personPlanInspected == personParent);
716 // calculate path width
717 const double pathWidth = s.addSize.getExaggeration(s, fromLane) * personPlanWidth * (duplicateWidth ? 2 : 1);
718 // get color
719 const RGBColor& color = drawUsingSelectColor() ? s.colorSettings.selectedPersonPlanColor : personPlanColor;
720 // Start drawing adding an gl identificator
722 // push a draw matrix
724 // Start with the drawing of the area traslating matrix to origin
726 // check if draw lane2lane connection or a red line
727 if (fromLane && fromLane->getLane2laneConnections().exist(toLane)) {
728 // obtain lane2lane geometry
729 const GUIGeometry& lane2laneGeometry = fromLane->getLane2laneConnections().getLane2laneGeometry(toLane);
730 // Set person plan color
731 GLHelper::setColor(color);
732 // draw lane2lane
733 GUIGeometry::drawGeometry(s, myNet->getViewNet()->getPositionInformation(), lane2laneGeometry, pathWidth);
734 } else {
735 // Set invalid person plan color
737 // draw line between end of first shape and first position of second shape
738 GLHelper::drawBoxLines({fromLane->getLaneShape().back(), toLane->getLaneShape().front()}, (0.5 * pathWidth));
739 }
740 // Pop last matrix
742 // Pop name
744 // draw lock icon
746 // check if shape dotted contour has to be drawn
747 if (fromLane->getLane2laneConnections().exist(toLane) && dottedElement) {
748 // check if mouse is over element
750 // inspect contour
753 pathWidth, 1, false, false);
754 }
755 // front contour
756 if (myNet->getViewNet()->getFrontAttributeCarrier() == this) {
758 pathWidth, 1, false, false);
759 }
760 // delete contour
761 if (myNet->getViewNet()->drawDeleteContour(this, this)) {
763 pathWidth, 1, false, false);
764 }
765 // select contour
766 if (myNet->getViewNet()->drawSelectContour(this, this)) {
768 pathWidth, 1, false, false);
769 }
770 }
771 }
772}
773
774
777 // get previous child
778 const auto previousChild = getParentDemandElements().at(0)->getPreviousChildDemandElement(this);
779 if (previousChild) {
780 // get previous edge
781 GNEEdge* previousEdge = nullptr;
782 if (previousChild->getParentLanes().size() == 1) {
783 previousEdge = previousChild->getParentLanes().front()->getParentEdge();
784 } else if (previousChild->getParentAdditionals().size() == 1) {
785 previousEdge = previousChild->getParentAdditionals().front()->getParentLanes().front()->getParentEdge();
786 } else if (previousChild->getParentEdges().size() > 0) {
787 previousEdge = previousChild->getParentEdges().back();
788 } else if (previousChild->getTagProperty().getTag() == GNE_TAG_WALK_ROUTE) {
789 previousEdge = previousChild->getParentDemandElements().at(1)->getParentEdges().back();
790 }
791 // get first edge
792 GNEEdge* firstEdge = nullptr;
793 // check edge
794 if (getParentLanes().size() == 1) {
795 firstEdge = getParentLanes().front()->getParentEdge();
796 } else if (getParentEdges().size() > 0) {
797 firstEdge = getParentEdges().front();
798 } else if (getParentAdditionals().size() == 1) {
799 firstEdge = getParentAdditionals().front()->getParentLanes().front()->getParentEdge();
800 } else if (getTagProperty().getTag() == GNE_TAG_WALK_ROUTE) {
801 firstEdge = getParentDemandElements().at(1)->getParentEdges().front();
802 }
803 // check junctions
804 if ((previousChild->getParentJunctions().size() > 0) && (getParentJunctions().size() > 0)) {
805 if (previousChild->getParentJunctions().back() != getParentJunctions().front()) {
807 }
808 } else if (previousEdge && (getParentJunctions().size() > 0)) {
809 if (previousEdge->getToJunction() != getParentJunctions().front()) {
811 }
812 } else if (previousEdge != firstEdge) {
814 }
815 }
816 // get next child
817 const auto nextChild = getParentDemandElements().at(0)->getNextChildDemandElement(this);
818 if (nextChild) {
819 // get previous edge
820 GNEEdge* nextEdge = nullptr;
821 if (nextChild->getParentLanes().size() == 1) {
822 nextEdge = nextChild->getParentLanes().front()->getParentEdge();
823 } else if (nextChild->getParentEdges().size() > 0) {
824 nextEdge = nextChild->getParentEdges().front();
825 } else if (nextChild->getParentAdditionals().size() == 1) {
826 nextEdge = nextChild->getParentAdditionals().front()->getParentLanes().front()->getParentEdge();
827 } else if (nextChild->getTagProperty().getTag() == GNE_TAG_WALK_ROUTE) {
828 nextEdge = nextChild->getParentDemandElements().at(1)->getParentEdges().front();
829 }
830 // get last edge
831 GNEEdge* lastEdge = nullptr;
832 // check edge
833 if (getParentLanes().size() == 1) {
834 lastEdge = getParentLanes().front()->getParentEdge();
835 } else if (getParentAdditionals().size() == 1) {
836 lastEdge = getParentAdditionals().front()->getParentLanes().front()->getParentEdge();
837 } else if (getParentEdges().size() > 0) {
838 lastEdge = getParentEdges().back();
839 } else if (getTagProperty().getTag() == GNE_TAG_WALK_ROUTE) {
840 lastEdge = getParentDemandElements().at(1)->getParentEdges().back();
841 }
842 // compare both edges
843 if ((nextChild->getParentJunctions().size() > 0) && (getParentJunctions().size() > 0)) {
844 if (nextChild->getParentJunctions().front() != getParentJunctions().back()) {
846 }
847 } else if (nextEdge && (getParentJunctions().size() > 0)) {
848 if (nextEdge->getFromJunction() != getParentJunctions().back()) {
850 }
851 } else if (lastEdge && (nextChild->getParentJunctions().size() > 0)) {
852 if (lastEdge->getToJunction() != nextChild->getParentJunctions().front()) {
854 }
855 } else if (nextEdge != lastEdge) {
857 }
858 }
859 // all ok, then return true
860 return Problem::OK;
861}
862
863
864std::string
866 // get previous child
867 const auto previousChild = getParentDemandElements().at(0)->getPreviousChildDemandElement(this);
868 if (previousChild) {
869 // get previous edge
870 GNEEdge* previousEdge = nullptr;
871 if (previousChild->getParentLanes().size() == 1) {
872 previousEdge = previousChild->getParentLanes().front()->getParentEdge();
873 } else if (previousChild->getParentAdditionals().size() == 1) {
874 previousEdge = previousChild->getParentAdditionals().front()->getParentLanes().front()->getParentEdge();
875 } else if (previousChild->getParentEdges().size() > 0) {
876 previousEdge = previousChild->getParentEdges().back();
877 } else if (previousChild->getTagProperty().getTag() == GNE_TAG_WALK_ROUTE) {
878 previousEdge = previousChild->getParentDemandElements().at(1)->getParentEdges().back();
879 }
880 // get first edge
881 GNEEdge* firstEdge = nullptr;
882 // check edge
883 if (getParentLanes().size() == 1) {
884 firstEdge = getParentLanes().front()->getParentEdge();
885 } else if (getParentEdges().size() > 0) {
886 firstEdge = getParentEdges().front();
887 } else if (getParentAdditionals().size() == 1) {
888 firstEdge = getParentAdditionals().front()->getParentLanes().front()->getParentEdge();
889 } else if (getTagProperty().getTag() == GNE_TAG_WALK_ROUTE) {
890 firstEdge = getParentDemandElements().at(1)->getParentEdges().front();
891 }
892 // compare elements
893 if ((previousChild->getParentJunctions().size() > 0) && (getParentJunctions().size() > 0)) {
894 return ("Junction '" + previousChild->getParentJunctions().back()->getID() +
895 "' is not consecutive with junction '" + getParentJunctions().front()->getID() + "'");
896 } else if (previousEdge && (getParentJunctions().size() > 0)) {
897 return ("edge '" + previousEdge->getID() + "' is not consecutive with junction '" + getParentJunctions().front()->getID() + "'");
898 } else if (previousEdge && firstEdge && (previousEdge != firstEdge)) {
899 return "Edge '" + previousEdge->getID() + "' is not consecutive with edge '" + firstEdge->getID() + "'";
900 }
901 }
902 // get next child
903 const auto nextChild = getParentDemandElements().at(0)->getNextChildDemandElement(this);
904 if (nextChild) {
905 // get previous edge
906 GNEEdge* nextEdge = nullptr;
907 if (nextChild->getParentLanes().size() == 1) {
908 nextEdge = nextChild->getParentLanes().front()->getParentEdge();
909 } else if (nextChild->getParentAdditionals().size() == 1) {
910 nextEdge = nextChild->getParentAdditionals().front()->getParentLanes().front()->getParentEdge();
911 } else if (nextChild->getParentEdges().size() > 0) {
912 nextEdge = nextChild->getParentEdges().front();
913 } else if (nextChild->getTagProperty().getTag() == GNE_TAG_WALK_ROUTE) {
914 nextEdge = nextChild->getParentDemandElements().at(1)->getParentEdges().front();
915 }
916 // get last edge
917 GNEEdge* lastEdge = nullptr;
918 // check edge
919 if (getParentLanes().size() == 1) {
920 lastEdge = getParentLanes().front()->getParentEdge();
921 } else if (getParentAdditionals().size() == 1) {
922 lastEdge = getParentAdditionals().front()->getParentLanes().front()->getParentEdge();
923 } else if (getParentEdges().size() > 0) {
924 lastEdge = getParentEdges().back();
925 } else if (getTagProperty().getTag() == GNE_TAG_WALK_ROUTE) {
926 lastEdge = getParentDemandElements().at(1)->getParentEdges().back();
927 }
928 // compare elements
929 if ((nextChild->getParentJunctions().size() > 0) && (getParentJunctions().size() > 0)) {
930 return ("Junction '" + nextChild->getParentJunctions().front()->getID() +
931 "' is not consecutive with junction '" + getParentJunctions().back()->getID() + "'");
932 } else if (nextEdge && (getParentJunctions().size() > 0)) {
933 return ("edge '" + nextEdge->getID() + "' is not consecutive with junction '" + getParentJunctions().back()->getID() + "'");
934 } else if (lastEdge && (nextChild->getParentJunctions().size() > 0)) {
935 return ("edge '" + lastEdge->getID() + "' is not consecutive with junction '" + nextChild->getParentJunctions().back()->getID() + "'");
936 } else if (nextEdge && lastEdge && (nextEdge != lastEdge)) {
937 return "Edge '" + lastEdge->getID() + "' is not consecutive with edge '" + nextEdge->getID() + "'";
938 }
939 }
940 // undefined problem
941 return "undefined problem";
942}
943
944
945void
947 // get two points
948 const Position posA = element->getParentJunctions().front()->getPositionInView();
949 const Position posB = element->getParentJunctions().back()->getPositionInView();
950 const double rot = ((double)atan2((posB.x() - posA.x()), (posA.y() - posB.y())) * (double) 180.0 / (double)M_PI);
951 const double len = posA.distanceTo2D(posB);
952 // push draw matrix
954 // Start with the drawing of the area traslating matrix to origin
956 // set trip color
958 // draw line
959 GLHelper::drawBoxLine(posA, rot, len, 0.25);
960 // pop draw matrix
962}
963
964
965void
966GNEDemandElement::drawStackLabel(const int number, const std::string& element, const Position& position, const double rotation, const double width, const double length, const double exaggeration) const {
967 // declare contour width
968 const double contourWidth = (0.05 * exaggeration);
969 // Push matrix
971 // Traslate to top
972 glTranslated(position.x(), position.y(), GLO_ROUTE + getType() + 0.1 + GLO_PERSONFLOW);
973 glRotated(rotation, 0, 0, -1);
974 glTranslated((width * exaggeration * 0.5) + (0.35 * exaggeration), 0, 0);
975 // draw external box
977 GLHelper::drawBoxLine(Position(), 0, (length * exaggeration), 0.3 * exaggeration);
978 // draw internal box
979 glTranslated(0, 0, 0.1);
980 GLHelper::setColor(RGBColor(0, 128, 0));
981 GLHelper::drawBoxLine(Position(0, -contourWidth), Position(0, -contourWidth), 0, (length * exaggeration) - (contourWidth * 2), (0.3 * exaggeration) - contourWidth);
982 // draw stack label
983 GLHelper::drawText(element + "s stacked: " + toString(number), Position(0, length * exaggeration * -0.5), (.1 * exaggeration), (0.6 * exaggeration), RGBColor::WHITE, 90, 0, -1);
984 // pop draw matrix
986}
987
988
989void
990GNEDemandElement::drawFlowLabel(const Position& position, const double rotation, const double width, const double length, const double exaggeration) const {
991 // declare contour width
992 const double contourWidth = (0.05 * exaggeration);
993 // Push matrix
995 // Traslate to bot
996 glTranslated(position.x(), position.y(), GLO_ROUTE + getType() + 0.1 + GLO_PERSONFLOW);
997 glRotated(rotation, 0, 0, -1);
998 glTranslated(-1 * ((width * 0.5 * exaggeration) + (0.35 * exaggeration)), 0, 0);
999 // draw external box
1001 GLHelper::drawBoxLine(Position(), Position(), 0, (length * exaggeration), 0.3 * exaggeration);
1002 // draw internal box
1003 glTranslated(0, 0, 0.1);
1005 GLHelper::drawBoxLine(Position(0, -contourWidth), Position(0, -contourWidth), 0, (length * exaggeration) - (contourWidth * 2), (0.3 * exaggeration) - contourWidth);
1006 // draw stack label
1007 GLHelper::drawText("Flow", Position(0, length * exaggeration * -0.5), (.1 * exaggeration), (0.6 * exaggeration), RGBColor::BLACK, 90, 0, -1);
1008 // pop draw matrix
1010}
1011
1012
1013void
1015 replaceParentElements(this, parse<std::vector<GNEEdge*> >(getNet(), value));
1016}
1017
1018
1019void
1021 replaceParentElements(this, parse<std::vector<GNELane*> >(getNet(), value));
1022}
1023
1024
1025void
1027 std::vector<GNEJunction*> parentJunctions = getParentJunctions();
1028 parentJunctions[0] = myNet->getAttributeCarriers()->retrieveJunction(value);
1029 // replace parent junctions
1030 replaceParentElements(this, parentJunctions);
1031}
1032
1033
1034void
1036 std::vector<GNEJunction*> parentJunctions = getParentJunctions();
1037 parentJunctions[(int)parentJunctions.size() - 1] = myNet->getAttributeCarriers()->retrieveJunction(value);
1038 // replace parent junctions
1039 replaceParentElements(this, parentJunctions);
1040}
1041
1042
1043void
1045 std::vector<GNEEdge*> parentEdges = getParentEdges();
1046 parentEdges[0] = myNet->getAttributeCarriers()->retrieveEdge(value);
1047 // replace parent edges
1048 replaceParentElements(this, parentEdges);
1049}
1050
1051
1052void
1054 std::vector<GNEEdge*> parentEdges = getParentEdges();
1055 parentEdges[(int)parentEdges.size() - 1] = myNet->getAttributeCarriers()->retrieveEdge(value);
1056 // replace parent edges
1057 replaceParentElements(this, parentEdges);
1058}
1059
1060
1061void
1063 std::vector<GNEAdditional*> parentAdditionals = getParentAdditionals();
1064 parentAdditionals[0] = myNet->getAttributeCarriers()->retrieveAdditional(tag, value);
1065 // replace parent additionals
1066 replaceParentElements(this, parentAdditionals);
1067}
1068
1069
1070void
1072 std::vector<GNEAdditional*> parentAdditionals = getParentAdditionals();
1073 parentAdditionals[(int)parentAdditionals.size() - 1] = myNet->getAttributeCarriers()->retrieveAdditional(tag, value);
1074 // replace parent additionals
1075 replaceParentElements(this, parentAdditionals);
1076}
1077
1078
1079void
1080GNEDemandElement::replaceDemandElementParent(SumoXMLTag tag, const std::string& value, const int parentIndex) {
1081 std::vector<GNEDemandElement*> parentDemandElements = getParentDemandElements();
1082 parentDemandElements[parentIndex] = myNet->getAttributeCarriers()->retrieveDemandElement(tag, value);
1083 // replace parent demand elements
1084 replaceParentElements(this, parentDemandElements);
1085}
1086
1087
1088void
1090 std::vector<GNEDemandElement*> parents;
1091 if (value.size() > 0) {
1093 }
1094 replaceParentElements(this, parents);
1095}
1096
1097
1098bool
1099GNEDemandElement::demandElementExist(const std::string &id, const std::vector<SumoXMLTag> tags) const {
1100 // check if there is a demand element with the given tags and id
1101 for (const auto& tag : tags) {
1102 if (myNet->getAttributeCarriers()->retrieveDemandElement(tag, id, false) != nullptr) {
1103 return true;
1104 }
1105 }
1106 return false;
1107}
1108
1109
1110bool
1112 // throw exception because this function mus be implemented in child (see GNEE3Detector)
1113 throw ProcessError(StringUtils::format("Calling non-implemented function checkChildDemandElementRestriction during saving of %. It muss be reimplemented in child class", getTagStr()));
1114}
1115
1116
1117std::vector<GNEDemandElement::EdgeStopIndex>
1119 std::vector<GNEDemandElement::EdgeStopIndex> edgeStopIndex;
1120 // first check that this stop has parent
1121 if (getParentDemandElements().size() > 0) {
1122 // get path edges depending of parent
1123 std::vector<GNEEdge*> pathEdges;
1124 // get parent demand element
1125 const auto parent = getParentDemandElements().front();
1126 // continue depending of parent
1127 if (parent->getTagProperty().hasAttribute(SUMO_ATTR_EDGES)) {
1128 pathEdges = parent->getParentEdges();
1129 } else if (parent->getTagProperty().hasAttribute(SUMO_ATTR_ROUTE)) {
1130 // get route edges
1131 if (parent->getParentDemandElements().size() > 1) {
1132 pathEdges = parent->getParentDemandElements().at(1)->getParentEdges();
1133 }
1134 } else if (parent->getTagProperty().hasEmbeddedRoute()) {
1135 // get embedded route edges
1136 pathEdges = parent->getChildDemandElements().front()->getParentEdges();
1137 } else {
1138 // get last parent edge
1139 const auto lastEdge = parent->getParentEdges().back();
1140 bool stop = false;
1141 const auto& pathElementSegments = myNet->getPathManager()->getPathElementSegments(parent);
1142 // extract all edges from pathElement parent
1143 for (auto it = pathElementSegments.begin(); (it != pathElementSegments.end()) && !stop; it++) {
1144 if ((*it)->getLane()) {
1145 pathEdges.push_back((*it)->getLane()->getParentEdge());
1146 // stop if path correspond to last edge
1147 if (pathEdges.back() == lastEdge) {
1148 stop = true;
1149 }
1150 }
1151 }
1152 }
1153 // get all parent's stops and waypoints sorted by position
1154 for (const auto& demandElement : parent->getChildDemandElements()) {
1155 if (demandElement->getTagProperty().isStop() || demandElement->getTagProperty().isWaypoint()) {
1156 // get stop/waypoint edge
1157 GNEEdge* edge = nullptr;
1158 if (demandElement->getParentAdditionals().size() > 0) {
1159 edge = demandElement->getParentAdditionals().front()->getParentLanes().front()->getParentEdge();
1160 } else {
1161 edge = demandElement->getParentLanes().front()->getParentEdge();
1162 }
1163 // check if add a new edgeStopIndex or update last
1164 if ((edgeStopIndex.size() > 0) && (edgeStopIndex.back().edge == edge)) {
1165 edgeStopIndex.back().stops.push_back(demandElement);
1166 } else {
1167 edgeStopIndex.push_back(EdgeStopIndex(edge, demandElement));
1168 }
1169 }
1170 }
1171 // declare index for current stop
1172 int currentEdgeStopIndex = 0;
1173 for (int i = 0; (i < (int)pathEdges.size()) && (currentEdgeStopIndex < (int)edgeStopIndex.size()); i++) {
1174 // check if current edge stop index is in the path
1175 if (edgeStopIndex[currentEdgeStopIndex].edge == pathEdges.at(i)) {
1176 edgeStopIndex[currentEdgeStopIndex].stopIndex = i;
1177 currentEdgeStopIndex++;
1178 } else {
1179 // check if edge exist in the rest of the path
1180 bool next = false;
1181 for (int j = (i + 1); j < (int)pathEdges.size(); j++) {
1182 if (edgeStopIndex[currentEdgeStopIndex].edge == pathEdges.at(j)) {
1183 next = true;
1184 }
1185 }
1186 if (!next) {
1187 // ignore current stops (because is out of path)
1188 currentEdgeStopIndex++;
1189 }
1190 }
1191 }
1192 }
1193 // sort stops by position
1194 for (auto& edgeStop : edgeStopIndex) {
1195 if (edgeStop.stops.size() > 1) {
1196 // copy all stops to a map to sort it by endPos
1197 std::map<double, std::vector<GNEDemandElement*> > sortedStops;
1198 for (const auto& stop : edgeStop.stops) {
1199 if (sortedStops.count(stop->getAttributeDouble(SUMO_ATTR_ENDPOS)) == 0) {
1200 sortedStops[stop->getAttributeDouble(SUMO_ATTR_ENDPOS)] = {stop};
1201 } else {
1202 sortedStops[stop->getAttributeDouble(SUMO_ATTR_ENDPOS)].push_back(stop);
1203 }
1204 }
1205 // update stops with sorted stops
1206 edgeStop.stops.clear();
1207 for (const auto& sortedStop : sortedStops) {
1208 edgeStop.stops.insert(edgeStop.stops.end(), sortedStop.second.begin(), sortedStop.second.end());
1209 }
1210 }
1211 }
1212 return edgeStopIndex;
1213}
1214
1215
1216void
1217GNEDemandElement::setFlowParameters(SUMOVehicleParameter* vehicleParameters, const SumoXMLAttr attribute, const bool value) {
1218 // modify parameters depending of given Flow attribute
1219 if (value) {
1220 switch (attribute) {
1221 case SUMO_ATTR_END:
1222 vehicleParameters->parametersSet |= VEHPARS_END_SET;
1223 break;
1224 case SUMO_ATTR_NUMBER:
1225 vehicleParameters->parametersSet |= VEHPARS_NUMBER_SET;
1226 break;
1230 vehicleParameters->parametersSet |= VEHPARS_VPH_SET;
1231 break;
1232 case SUMO_ATTR_PERIOD:
1233 vehicleParameters->parametersSet |= VEHPARS_PERIOD_SET;
1234 break;
1235 case GNE_ATTR_POISSON:
1236 vehicleParameters->parametersSet |= VEHPARS_POISSON_SET;
1237 break;
1238 case SUMO_ATTR_PROB:
1239 vehicleParameters->parametersSet |= VEHPARS_PROB_SET;
1240 break;
1241 default:
1242 break;
1243 }
1244 } else {
1245 switch (attribute) {
1246 case SUMO_ATTR_END:
1247 vehicleParameters->parametersSet &= ~VEHPARS_END_SET;
1248 break;
1249 case SUMO_ATTR_NUMBER:
1250 vehicleParameters->parametersSet &= ~VEHPARS_NUMBER_SET;
1251 break;
1255 vehicleParameters->parametersSet &= ~VEHPARS_VPH_SET;
1256 break;
1257 case SUMO_ATTR_PERIOD:
1258 vehicleParameters->parametersSet &= ~VEHPARS_PERIOD_SET;
1259 break;
1260 case GNE_ATTR_POISSON:
1261 vehicleParameters->parametersSet &= ~VEHPARS_POISSON_SET;
1262 break;
1263 case SUMO_ATTR_PROB:
1264 vehicleParameters->parametersSet &= ~VEHPARS_PROB_SET;
1265 break;
1266 default:
1267 break;
1268 }
1269 }
1270}
1271
1272
1273void
1275 // first check that this demand element is a flow
1276 if (myTagProperty.isFlow()) {
1277 // end
1278 if ((vehicleParameters->parametersSet & VEHPARS_END_SET) == 0) {
1280 }
1281 // number
1282 if ((vehicleParameters->parametersSet & VEHPARS_NUMBER_SET) == 0) {
1284 }
1285 // vehicles/person/container per hour
1286 if (((vehicleParameters->parametersSet & VEHPARS_PERIOD_SET) == 0) &&
1287 ((vehicleParameters->parametersSet & VEHPARS_POISSON_SET) == 0) &&
1288 ((vehicleParameters->parametersSet & VEHPARS_VPH_SET) == 0)) {
1290 }
1291 // probability
1292 if ((vehicleParameters->parametersSet & VEHPARS_PROB_SET) == 0) {
1294 }
1295 // poisson
1296 if (vehicleParameters->repetitionOffset < 0) {
1299 setAttribute(GNE_ATTR_POISSON, time2string(vehicleParameters->repetitionOffset * -1));
1300 }
1301 }
1302}
1303
1304
1305void
1307 std::vector<GNEEdge*> edges;
1308 if (myTagProperty.isRoute()) {
1309 edges = getParentEdges();
1310 } else if ((getParentDemandElements().size() > 1) && getParentDemandElements().at(1)->getTagProperty().isRoute()) {
1311 edges = getParentDemandElements().at(1)->getParentEdges();
1312 } else if ((getChildDemandElements().size() > 0) && getChildDemandElements().front()->getTagProperty().isRoute()) {
1313 edges = getChildDemandElements().front()->getParentEdges();
1314 } else if (getParentEdges().size() > 0) {
1315 edges = getParentEdges();
1316 }
1317 // calculate path
1318 const auto path = myNet->getPathManager()->getPathCalculator()->calculateDijkstraPath(getVClass(), edges);
1319 // check path size
1320 if (path.size() > 0) {
1321 double length = 0;
1322 for (const auto& edge : path) {
1323 length += edge->getNBEdge()->getFinalLength();
1324 }
1325 for (int i = 0; i < ((int)path.size() - 1); i++) {
1326 length += path.at(i)->getLanes().front()->getLane2laneConnections().getLane2laneGeometry(path.at(i + 1)->getLanes().front()).getShape().length();
1327 }
1328 GUIDesigns::buildFXMenuCommand(ret, "Route length: " + toString(length), nullptr, ret, MID_COPY_NAME);
1329 }
1330}
1331
1332/****************************************************************************/
@ 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
GUIGlObjectType
@ GLO_ROUTE
a route
@ GLO_PERSONFLOW
a person flow
std::string time2string(SUMOTime t, bool humanReadable)
convert SUMOTime to string (independently of global format setting)
Definition SUMOTime.cpp:69
const int VEHPARS_PROB_SET
const int VEHPARS_VPH_SET
const int VEHPARS_END_SET
const int VEHPARS_POISSON_SET
const int VEHPARS_NUMBER_SET
const int VEHPARS_PERIOD_SET
SumoXMLTag
Numbers representing SUMO-XML - element names.
@ SUMO_TAG_VTYPE
description of a vehicle/person/container type
@ GNE_TAG_STOPPERSON_BUSSTOP
@ SUMO_TAG_ROUTE
begin/end of the description of a route
@ SUMO_TAG_VTYPE_DISTRIBUTION
distribution of a vehicle type
@ GNE_TAG_STOPPERSON_TRAINSTOP
@ GNE_TAG_ROUTE_EMBEDDED
embedded route
@ GNE_TAG_WALK_ROUTE
SumoXMLAttr
Numbers representing SUMO-XML - attributes.
@ SUMO_ATTR_NUMBER
@ SUMO_ATTR_VEHSPERHOUR
@ SUMO_ATTR_ENDPOS
@ GNE_ATTR_PARENT
parent of an additional element
@ SUMO_ATTR_ARRIVALPOS
@ GNE_ATTR_VTYPE_DISTRIBUTION
vehicle type distribution
@ SUMO_ATTR_EDGES
the edges of a route
@ GNE_ATTR_POISSON
poisson definition (used in flow)
@ SUMO_ATTR_CONTAINERSPERHOUR
@ SUMO_ATTR_DEPARTPOS
@ SUMO_ATTR_PERIOD
@ SUMO_ATTR_CENTER
@ SUMO_ATTR_END
weights: time range end
@ SUMO_ATTR_PROB
@ SUMO_ATTR_ROUTE
@ SUMO_ATTR_PERSONSPERHOUR
T MIN2(T a, T b)
Definition StdDefs.h:76
const double SUMO_const_halfLaneWidth
Definition StdDefs.h:49
std::string toString(const T &t, std::streamsize accuracy=gPrecision)
Definition ToString.h:46
static void setColor(const RGBColor &c)
Sets the gl-color to this value.
Definition GLHelper.cpp:583
static void drawFilledCircle(double width, int steps=8)
Draws a filled circle around (0,0)
Definition GLHelper.cpp:498
static void pushName(unsigned int name)
push Name
Definition GLHelper.cpp:139
static void popMatrix()
pop matrix
Definition GLHelper.cpp:130
static void drawBoxLines(const PositionVector &geom, const std::vector< double > &rots, const std::vector< double > &lengths, double width, int cornerDetail=0, double offset=0)
Draws thick lines.
Definition GLHelper.cpp:329
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
static void drawText(const std::string &text, const Position &pos, const double layer, const double size, const RGBColor &col=RGBColor::BLACK, const double angle=0, const int align=0, double width=-1)
Definition GLHelper.cpp:685
An Element which don't belong to GNENet but has influence in the simulation.
const GUIGeometry & getAdditionalGeometry() const
obtain additional geometry
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
bool mySelected
boolean to check if this AC is selected (instead of GUIGlObjectStorage)
bool myIsTemplate
whether the current object is a template object (not drawn in the view)
virtual void toggleAttribute(SumoXMLAttr key, const bool value)
method for enable or disable the attribute and nothing else (used in GNEChange_EnableAttribute)
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
const GNETagProperties & getTagProperty() const
get tagProperty associated with this Attribute Carrier
void unselectAttributeCarrier(const bool changeFlag=true)
unselect attribute carrier using GUIGlobalSelection
bool drawUsingSelectColor() const
check if attribute carrier must be drawn using selecting color.
GNENet * myNet
pointer to net
GNENet * getNet() const
get pointer to net
void selectAttributeCarrier(const bool changeFlag=true)
select attribute carrier using GUIGlobalSelection
virtual std::string getAttribute(SumoXMLAttr key) const =0
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 void updateGeometry()=0
update pre-computed geometry information
std::vector< GNEDemandElement * > getInvalidStops() const
get invalid stops
virtual SUMOVehicleClass getVClass() const =0
void updateDemandElementGeometry(const GNELane *lane, const double posOverLane)
update element stacked geometry (stacked)
void replaceDemandElementParent(SumoXMLTag tag, const std::string &value, const int parentIndex)
replace demand element parent
void drawStackLabel(const int number, const std::string &element, const Position &position, const double rotation, const double width, const double length, const double exaggeration) const
draw stack label
virtual std::string getBegin() const
get begin time of demand element
Problem isPersonPlanValid() const
check if person plan is valid
virtual GNELane * getFirstPathLane() const =0
get first path lane
Position getPathElementArrivalPos() const
get path element arrival position
GUIGeometry myDemandElementGeometry
demand element geometry (also called "stacked geometry")
virtual double getAttributeDouble(SumoXMLAttr key) const =0
GNEDemandElement * getNextChildDemandElement(const GNEDemandElement *demandElement) const
get next child demand element to the given demand element
void updateDemandElementStackLabel(const int stack)
update stack label
void drawFlowLabel(const Position &position, const double rotation, const double width, const double length, const double exaggeration) const
draw flow label
void replaceLastParentEdge(const std::string &value)
replace the last parent edge
void drawJunctionLine(const GNEDemandElement *element) const
draw line between junctions
virtual std::string getAttribute(SumoXMLAttr key) const =0
GUIGlObject * getGUIGlObject()
get GUIGlObject associated with this AttributeCarrier
bool isPathElementSelected() const
check if path element is selected
void replaceFirstParentAdditional(SumoXMLTag tag, const std::string &value)
replace the first parent additional
double getPathElementArrivalValue() const
get path element arrival lane pos
GNEDemandElement * getRouteParent() const
get route parent (always the second parent demand element)
void selectGLObject()
select element
bool drawContainerPlan() const
check if container plan can be drawn
GUIGeometry mySpreadGeometry
demand element spread geometry (Only used by vehicles and pedestrians)
std::string getPersonPlanProblem() const
get person plan problem
void replaceFirstParentJunction(const std::string &value)
replace the first parent junction
std::vector< EdgeStopIndex > getEdgeStopIndex() const
get edgeStopIndex
void setVTypeDistributionParent(const std::string &value)
set VTypeDistribution parent
void updateGLObject()
update GLObject (geometry, ID, etc.)
GNEDemandElement * getTypeParent() const
get type parent (needed because first parent can be either type or typeDistribution)
void replaceDemandParentLanes(const std::string &value)
replace demand parent lanes
bool demandElementExist(const std::string &id, const std::vector< SumoXMLTag > tags) const
check if the given demand element exist
void replaceFirstParentEdge(const std::string &value)
replace the first parent edge
bool isGLObjectLocked()
check if element is locked
int myStackedLabelNumber
stacked label number
GUIParameterTableWindow * getParameterWindow(GUIMainWindow &app, GUISUMOAbstractView &parent)
Returns an own parameter window.
void updateDemandElementSpreadGeometry(const GNELane *lane, const double posOverLane)
update element spread geometry
virtual Position getPositionInView() const =0
Returns position of demand element in view.
virtual void setAttribute(SumoXMLAttr key, const std::string &value, GNEUndoList *undoList)=0
method for setting the attribute and letting the object perform demand element changes
const GUIGeometry & getDemandElementGeometry()
get demand element geometry (stacked)
virtual GUIGLObjectPopupMenu * getPopUpMenu(GUIMainWindow &app, GUISUMOAbstractView &parent)
Returns an own popup-menu.
virtual bool checkChildDemandElementRestriction() const
check restriction with the number of children
const Position getBeginPosition(const double pedestrianDepartPos) const
get personPlan start position
Problem
enum class for demandElement problems
void removeGeometryPoint(const Position clickedPosition, GNEUndoList *undoList)
remove geometry point in the clicked position (Currently unused in shapes)
GNEDemandElement * getPreviousChildDemandElement(const GNEDemandElement *demandElement) const
get previous child demand element to the given demand element
Position getPathElementDepartPos() const
get path element depart position
void adjustDefaultFlowAttributes(SUMOVehicleParameter *vehicleParameters)
adjust flow default attributes (called in vehicle/person/flow constructors)
double getPathElementDepartValue() const
get path element depart lane pos
void markAsFrontElement()
mark element as front element
void setFlowParameters(SUMOVehicleParameter *vehicleParameters, const SumoXMLAttr attribute, const bool value)
set flow parameters (used in toggleAttribute(...) function of vehicles, persons and containers
void drawPersonPlanPartial(const bool drawPlan, const GUIVisualizationSettings &s, const GNELane *lane, const GNEPathManager::Segment *segment, const double offsetFront, const double personPlanWidth, const RGBColor &personPlanColor) const
draw person plan partial lane
bool isValidDemandElementID(const std::string &newID) const
check if a new demand element ID is valid
static const double myPersonPlanArrivalPositionDiameter
person plans arrival position radius
void replaceLastParentAdditional(SumoXMLTag tag, const std::string &value)
replace the last parent additional
virtual void drawGL(const GUIVisualizationSettings &s) const =0
Draws the object.
virtual ~GNEDemandElement()
Destructor.
virtual void openDemandElementDialog()
open DemandElement Dialog
void deleteGLObject()
delete element
bool drawPersonPlan() const
void replaceLastParentJunction(const std::string &value)
replace the last parent junction
virtual Position getAttributePosition(SumoXMLAttr key) const =0
A road/street connecting two junctions (netedit-version)
Definition GNEEdge.h:53
GNEJunction * getFromJunction() const
get from Junction (only used to increase readability)
Definition GNEEdge.h:77
GNEJunction * getToJunction() const
get from Junction (only used to increase readability)
Definition GNEEdge.h:82
const std::vector< GNEJunction * > & getParentJunctions() const
get parent junctions
const std::vector< GNEDemandElement * > & getChildDemandElements() const
return child demand elements
const std::vector< GNEDemandElement * > & getParentDemandElements() const
get parent demand elements
const std::vector< GNEAdditional * > & getParentAdditionals() const
get parent additionals
const std::vector< GNEEdge * > & getParentEdges() const
get parent edges
const std::vector< GNELane * > & getParentLanes() const
get parent lanes
void replaceParentElements(T *elementChild, const U &newParents)
replace parent elements
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
const GUIGeometry & getLaneGeometry() const
Definition GNELane.cpp:130
GNEEdge * getParentEdge() const
get parent edge
Definition GNELane.cpp:118
double myMoveElementLateralOffset
move element lateral offset (used by elements placed over lanes
const std::map< SumoXMLTag, std::set< GNEDemandElement * > > & getDemandElements() const
get demand elements
GNEAdditional * retrieveAdditional(SumoXMLTag type, const std::string &id, bool hardFail=true) const
Returns the named additional.
GNEJunction * retrieveJunction(const std::string &id, bool hardFail=true) const
get junction by id
GNEEdge * retrieveEdge(const std::string &id, bool hardFail=true) const
get edge by id
GNEDemandElement * retrieveDemandElement(SumoXMLTag type, const std::string &id, bool hardFail=true) const
Returns the named demand element.
A NBNetBuilder extended by visualisation and editing capabilities.
Definition GNENet.h:42
void deleteDemandElement(GNEDemandElement *demandElement, GNEUndoList *undoList)
remove demand element
Definition GNENet.cpp:641
GNENetHelper::AttributeCarriers * getAttributeCarriers() const
get all attribute carriers used in this net
Definition GNENet.cpp:120
GNEPathManager * getPathManager()
get path manager
Definition GNENet.cpp:132
GNEViewNet * getViewNet() const
get view net
Definition GNENet.cpp:2030
std::vector< GNEEdge * > calculateDijkstraPath(const SUMOVehicleClass vClass, const std::vector< GNEEdge * > &partialEdges) const
calculate Dijkstra path between a list of partial edges
bool drawPathGeometry(const bool dottedElement, const GNELane *lane, SumoXMLTag tag)
check if path element geometry must be drawn in the given lane
bool isRoute() const
check if pathElement is a route
Segment * getPreviousSegment() const
get previous segment
Segment * getNextSegment() const
get next segment
const GNELane * getLane() const
get lane associated with this 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
PathCalculator * getPathCalculator()
obtain instance of PathCalculator
const std::vector< Segment * > & getPathElementSegments(PathElement *pathElement) const
get path segments
PathDraw * getPathDraw()
obtain instance of PathDraw
const GNELane * getFirstLane(const PathElement *pathElement) const
get first lane associated with path element
void updateInformationLabel()
update information label
SelectionInformation * getSelectionInformation() const
get modul for selection information
bool isFlow() const
return true if tag correspond to a flow element
bool isPersonPlan() const
return true if tag correspond to a person plan
bool isRoute() const
return true if tag correspond to a route element
bool isStop() const
return true if tag correspond to a stop element
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
bool isWaypoint() const
return true if tag correspond to a waypoint element
bool isStopPerson() const
return true if tag correspond to a person stop element
const std::string & getDefaultValue(SumoXMLAttr attr) const
return the default value of the attribute of an element
bool isContainerPlan() const
return true if tag correspond to a container plan
bool isObjectLocked(GUIGlObjectType objectType, const bool selected) const
check if given GLObject is locked for inspect, select, delete and move
const GNEAttributeCarrier * getFrontAttributeCarrier() const
get front attributeCarrier
const GNEViewNetHelper::EditModes & getEditModes() const
get edit modes
void setFrontAttributeCarrier(GNEAttributeCarrier *AC)
set 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
const std::vector< GNEAttributeCarrier * > & getInspectedAttributeCarriers() const
get inspected attribute carriers
GNEViewNetHelper::LockManager & getLockManager()
get lock manager
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
GNESelectorFrame * getSelectorFrame() const
get frame for select elements
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
static void drawChildLine(const GUIVisualizationSettings &s, const Position &child, const Position &parent, const RGBColor &color, const bool drawEntire, const double lineWidth)
draw line between child and parent (used in netedit)
const PositionVector & getShape() const
The shape of the additional element.
void updateGeometry(const PositionVector &shape)
update entire geometry
void buildShowParamsPopupEntry(GUIGLObjectPopupMenu *ret, bool addSeparator=true)
Builds an entry which allows to open the parameter window.
virtual Boundary getCenteringBoundary() const =0
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
A window containing a gl-object's parameter.
void mkItem(const char *name, bool dynamic, ValueSource< T > *src)
Adds a row which obtains its value from a ValueSource.
void closeBuilding(const Parameterised *p=0)
Closes the building of the table.
virtual Position getPositionInformation() const
Returns the cursor's x/y position within the network.
Stores the information about how to visualize structures.
GUIVisualizationTextSettings addName
bool drawForRectangleSelection
whether drawing is performed for the purpose of selecting objects using a rectangle
GUIVisualizationSizeSettings addSize
double laneWidthExaggeration
The lane exaggeration (upscale thickness)
GUIVisualizationColorSettings colorSettings
color settings
double scale
information about a lane's width (temporary, used for a single view)
int getCircleResolution() const
function to calculate circle resolution for all circles drawn in drawGL(...) functions
A point in 2D or 3D with translation and scaling methods.
Definition Position.h:37
double distanceSquaredTo2D(const Position &p2) const
returns the square of the distance to another position (Only using x and y positions)
Definition Position.h:259
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 x() const
Returns the x-position.
Definition Position.h:55
double y() const
Returns the y-position.
Definition Position.h:60
double length2D() const
Returns the length.
Position positionAtOffset2D(double pos, double lateralOffset=0) const
Returns the position at the given length.
static const RGBColor WHITE
Definition RGBColor.h:192
unsigned char alpha() const
Returns the alpha-amount of the color.
Definition RGBColor.cpp:92
static const RGBColor GREY
Definition RGBColor.h:194
static const RGBColor CYAN
Definition RGBColor.h:189
static const RGBColor BLACK
Definition RGBColor.h:193
static const RGBColor RED
named colors
Definition RGBColor.h:185
Structure representing possible vehicle parameter.
int parametersSet
Information for the router which parameter were set, TraCI may modify this (when changing color)
SUMOTime repetitionOffset
The time offset between vehicle reinsertions.
static bool isValidVehicleID(const std::string &value)
whether the given string is a valid id for a vehicle or flow
static const std::string format(const std::string &format, T value, Targs... Fargs)
adds a new formatted message
#define M_PI
Definition odrSpiral.cpp:45
auxiliar struct used for calculate pathStopIndex
bool showAllPersonPlans() const
check all person plans has to be show
const GNEDemandElement * getLockedPerson() const
get locked person
const GNEDemandElement * getLockedContainer() const
get locked container
bool showAllContainerPlans() const
check all container plans has to be show
bool isCurrentSupermodeDemand() const
@check if current supermode is Demand
bool isCurrentSupermodeNetwork() const
@check if current supermode is Network
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 selectedPersonPlanColor
person plan selection color (Rides, Walks, stopPersons...)
double getExaggeration(const GUIVisualizationSettings &s, const GUIGlObject *o, double factor=20) const
return the drawing size including exaggeration and constantSize values