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-2025 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
29#include <netedit/GNENet.h>
30#include <netedit/GNESegment.h>
37
38#include "GNEDemandElement.h"
39#include "GNERouteHandler.h"
40
41// ===========================================================================
42// member method definitions
43// ===========================================================================
44#ifdef _MSC_VER
45#pragma warning(push)
46#pragma warning(disable: 4355) // mask warning about "this" in initializers
47#endif
48
50 GNEAttributeCarrier(tag, net),
51 GUIGlObject(myTagProperty->getGLType(), "", GUIIconSubSys::getIcon(myTagProperty->getGUIIcon())),
52 GNEPathElement(myTagProperty->isRoute() ? GNEPathElement::Options::DEMAND_ELEMENT | GNEPathElement::Options::ROUTE :
53 GNEPathElement::Options::DEMAND_ELEMENT) {
54}
55
56
57GNEDemandElement::GNEDemandElement(const std::string& id, GNENet* net, SumoXMLTag tag, FileBucket* fileBucket) :
58 GNEAttributeCarrier(tag, net, fileBucket),
59 GUIGlObject(myTagProperty->getGLType(), id, GUIIconSubSys::getIcon(myTagProperty->getGUIIcon())),
60 GNEPathElement(myTagProperty->isRoute() ? GNEPathElement::Options::DEMAND_ELEMENT | GNEPathElement::Options::ROUTE :
61 GNEPathElement::Options::DEMAND_ELEMENT) {
62}
63
64
66 GNEAttributeCarrier(tag, demandElementParent->getNet(), demandElementParent->getFileBucket()),
67 GUIGlObject(myTagProperty->getGLType(), demandElementParent->getID(), GUIIconSubSys::getIcon(myTagProperty->getGUIIcon())),
68 GNEPathElement(myTagProperty->isRoute() ? GNEPathElement::Options::DEMAND_ELEMENT | GNEPathElement::Options::ROUTE :
69 GNEPathElement::Options::DEMAND_ELEMENT) {
70}
71#ifdef _MSC_VER
72#pragma warning(pop)
73#endif
74
76
77
82
83
86 return this;
87}
88
89
90const GUIGlObject*
92 return this;
93}
94
95
99 if (isTemplate()) {
100 return nullptr;
101 } else {
102 return getParentDemandElements().front()->getFileBucket();
103 }
104 } else {
105 return myFileBucket;
106 }
107}
108
109
110void
113 myFileBucket = fileBucket;
114 myFileBucket->addElement(false);
115 // update options
117 // mark demand elements to save
120}
121
122
123const GUIGeometry&
127
128
131 // first check if there are demand elements
132 if (getChildDemandElements().empty()) {
133 return nullptr;
134 } else {
135 // find child demand element
136 auto it = std::find(getChildDemandElements().begin(), getChildDemandElements().end(), demandElement);
137 // return element or null depending of iterator
138 if (it == getChildDemandElements().end()) {
139 // in this case, we assume that the last child is the previos child
140 return getChildDemandElements().back();
141 } else if (it == getChildDemandElements().begin()) {
142 return nullptr;
143 } else {
144 return *(it - 1);
145 }
146 }
147}
148
149
152 // find child demand element
153 auto it = std::find(getChildDemandElements().begin(), getChildDemandElements().end(), demandElement);
154 // return element or null depending of iterator
155 if (it == getChildDemandElements().end()) {
156 return nullptr;
157 } else if (it == (getChildDemandElements().end() - 1)) {
158 return nullptr;
159 } else {
160 return *(it + 1);
161 }
162}
163
164
165void
166GNEDemandElement::updateDemandElementGeometry(const GNELane* lane, const double posOverLane) {
167 myDemandElementGeometry.updateGeometry(lane->getLaneShape(), posOverLane, /*myMovingLateralOffset*/ 0);
168}
169
170
171void
175
176
177void
178GNEDemandElement::updateDemandElementSpreadGeometry(const GNELane* lane, const double posOverLane) {
179 mySpreadGeometry.updateGeometry(lane->getLaneShape(), posOverLane, /*myMovingLateralOffset*/ 0);
180}
181
182
183const GUIGeometry&
187
188
189bool
191 return false;
192}
193
194
195bool
197 return false;
198}
199
200
201bool
204 // check if inspected parent is inspected
205 for (const auto& inspectedAC : myNet->getViewNet()->getInspectedElements().getACs()) {
206 if (inspectedAC->getTagProperty()->vehicleRouteEmbedded()) {
207 const auto demandElement = dynamic_cast<GNEDemandElement*>(inspectedAC);
208 if (demandElement && (demandElement->getChildDemandElements().size() > 0) &&
209 (demandElement->getChildDemandElements().at(0) == this)) {
210 return true;
211 }
212 }
213 }
214 }
215 // check opened popup
216 if (myNet->getViewNet()->getPopup()) {
217 return myNet->getViewNet()->getPopup()->getGLObject() == this;
218 }
219 return false;
220}
221
222
223bool
225 // get modes
226 const auto& modes = myNet->getViewNet()->getEditModes();
227 // get frames
228 const auto& personFramePlanSelector = myNet->getViewParent()->getPersonFrame()->getPlanSelector();
229 const auto& personPlanFramePlanSelector = myNet->getViewParent()->getPersonPlanFrame()->getPlanSelector();
230 const auto& containerFramePlanSelector = myNet->getViewParent()->getContainerFrame()->getPlanSelector();
231 const auto& containerPlanFramePlanSelector = myNet->getViewParent()->getContainerPlanFrame()->getPlanSelector();
232 // special case for Route
234 // get vehicle frame
235 const auto& vehicleFrame = myNet->getViewParent()->getVehicleFrame();
236 // check if we're in vehicle mode
237 if (vehicleFrame->shown()) {
238 // get current vehicle template
239 const auto& vehicleTemplate = vehicleFrame->getVehicleTagSelector()->getCurrentTemplateAC();
240 // check if vehicle can be placed over route
241 if (vehicleTemplate && vehicleTemplate->getTagProperty()->vehicleRoute()) {
243 }
244 } else if (modes.isCurrentSupermodeDemand()) {
245 // check if we're in person or personPlan modes
246 if (((modes.demandEditMode == DemandEditMode::DEMAND_PERSON) && personFramePlanSelector->markRoutes()) ||
247 ((modes.demandEditMode == DemandEditMode::DEMAND_PERSONPLAN) && personPlanFramePlanSelector->markRoutes()) ||
248 ((modes.demandEditMode == DemandEditMode::DEMAND_CONTAINER) && containerFramePlanSelector->markRoutes()) ||
249 ((modes.demandEditMode == DemandEditMode::DEMAND_CONTAINERPLAN) && containerPlanFramePlanSelector->markRoutes())) {
251 }
252 }
253 }
254 return false;
255}
256
257
258bool
260 // get edit modes
261 const auto& editModes = myNet->getViewNet()->getEditModes();
262 // check if we're in delete mode
263 if (editModes.isCurrentSupermodeDemand() && (editModes.demandEditMode == DemandEditMode::DEMAND_DELETE)) {
265 } else {
266 return false;
267 }
268}
269
270
271bool
275 if (route && (route == myNet->getViewNet()->getViewObjectsSelector().getAttributeCarrierFront())) {
276 return (getParentDemandElements().at(1) == route);
277 }
280 if (vehicle && (vehicle == myNet->getViewNet()->getViewObjectsSelector().getAttributeCarrierFront())) {
281 return (getParentDemandElements().front() == vehicle);
282 }
283 }
284 return false;
285}
286
287
288bool
290 // get edit modes
291 const auto& editModes = myNet->getViewNet()->getEditModes();
292 // check if we're in select mode
293 if (editModes.isCurrentSupermodeDemand() && (editModes.demandEditMode == DemandEditMode::DEMAND_SELECT)) {
295 } else {
296 return false;
297 }
298}
299
300
301bool
303 // get edit modes
304 const auto& editModes = myNet->getViewNet()->getEditModes();
305 // check first set of conditions
306 if (!myNet->getViewNet()->isCurrentlyMovingElements() && // another elements are not currently moved
307 editModes.isCurrentSupermodeDemand() && // supermode demand
308 (editModes.demandEditMode == DemandEditMode::DEMAND_MOVE) && // move mode
309 myNet->getViewNet()->checkOverLockedElement(this, mySelected) && // no locked
310 myNet->getViewNet()->getViewObjectsSelector().getGUIGlObjectFront() == this) { // first element
311 // continue depending of subtype
312 if (myTagProperty->isVehicle()) {
313 // only vehicles over edges can be moved
315 return true;
316 } else {
317 return false;
318 }
319 } else if ((myTagProperty->isPerson() || myTagProperty->isContainer()) && (getChildDemandElements().size() > 0)) {
320 // only persons/containers with their first plan over edge can be moved
321 return getChildDemandElements().front()->getTagProperty()->planFromEdge();
322 } else {
323 return false;
324 }
325 } else {
326 return false;
327 }
328}
329
330
331void
333 throw InvalidArgument(getTagStr() + " doesn't have a demand element dialog");
334}
335
336
339 // create popup
340 GUIGLObjectPopupMenu* ret = new GUIGLObjectPopupMenu(app, parent, this);
341 // build common options
343 // show option to open demand element dialog
344 if (myTagProperty->hasDialog()) {
345 GUIDesigns::buildFXMenuCommand(ret, ("Open " + getTagStr() + " Dialog").c_str(), getACIcon(), &parent, MID_OPEN_ADDITIONAL_DIALOG);
346 new FXMenuSeparator(ret);
347 }
348 GUIDesigns::buildFXMenuCommand(ret, "Cursor position in view: " + toString(getPositionInView().x()) + "," + toString(getPositionInView().y()), nullptr, nullptr, 0);
349 return ret;
350}
351
352
355 // Create table
357 // Iterate over attributes
358 for (const auto& attrProperty : myTagProperty->getAttributeProperties()) {
359 // Add attribute and set it dynamic if aren't unique
360 if (attrProperty->isUnique()) {
361 ret->mkItem(attrProperty->getAttrStr().c_str(), false, getAttribute(attrProperty->getAttr()));
362 } else {
363 ret->mkItem(attrProperty->getAttrStr().c_str(), true, getAttribute(attrProperty->getAttr()));
364 }
365 }
366 // close building
367 ret->closeBuilding();
368 return ret;
369}
370
371
372bool
380
381
382void
386
387
388void
390 // we need an special checks due hierarchies
391 if (myTagProperty->isPlan()) {
392 // get person/container plarent
393 GNEDemandElement* planParent = getParentDemandElements().front();
394 // if this is the last person/container plan element, remove parent instead plan
395 if (planParent->getChildDemandElements().size() == 1) {
396 planParent->deleteGLObject();
397 } else {
399 }
401 // remove parent demand element
402 getParentDemandElements().front()->deleteGLObject();
403 } else {
405 }
406}
407
408
409void
419
420
421void
425
426
431
432
437
438
439bool
443
444// ---------------------------------------------------------------------------
445// GNEDemandElement - protected methods
446// ---------------------------------------------------------------------------
447
448bool
449GNEDemandElement::isValidDemandElementID(const std::string& value) const {
450 if (!isTemplate() && (value == getID())) {
451 return true;
452 } else if (SUMOXMLDefinitions::isValidVehicleID(value)) {
453 return (myNet->getAttributeCarriers()->retrieveDemandElement(myTagProperty->getTag(), value, false) == nullptr);
454 } else {
455 return false;
456 }
457}
458
459
460bool
461GNEDemandElement::isValidDemandElementID(const std::vector<SumoXMLTag>& tags, const std::string& value) const {
462 if (isTemplate() && value.empty()) {
463 return true;
464 } else if (!isTemplate() && (value == getID())) {
465 return true;
466 } else if (SUMOXMLDefinitions::isValidVehicleID(value)) {
467 return (myNet->getAttributeCarriers()->retrieveDemandElements(tags, value, false) == nullptr);
468 } else {
469 return false;
470 }
471}
472
473
474void
475GNEDemandElement::setDemandElementID(const std::string& newID) {
476 // update ID
478 setMicrosimID(newID);
479 } else {
481 }
482 // check if update ids of child elements
484 // Change IDs of all person plans children (stops, embedded routes...)
485 for (const auto& childDemandElement : getChildDemandElements()) {
486 childDemandElement->setDemandElementID(getID());
487 }
488 }
489}
490
491
494 if (getParentDemandElements().size() < 1) {
495 throw InvalidArgument("This demand element doesn't have a type parent");
496 } else if ((getParentDemandElements().at(0)->getTagProperty()->isType()) ||
497 (getParentDemandElements().at(0)->getTagProperty()->isTypeDistribution())) {
498 return getParentDemandElements().at(0);
499 } else {
500 throw InvalidArgument("The first parent isn't a type");
501 }
502}
503
504
507 if (getParentDemandElements().size() < 2) {
508 throw InvalidArgument("This demand element doesn't have a route parent");
509 } else if ((getParentDemandElements().at(1)->getTagProperty()->isRoute()) ||
510 (getParentDemandElements().at(1)->getTagProperty()->isRouteDistribution())) {
511 return getParentDemandElements().at(1);
512 } else {
513 throw InvalidArgument("The second parent isn't a route");
514 }
515}
516
517
518std::vector<GNEDemandElement*>
521 // get stops
522 std::vector<GNEDemandElement*> invalidStops;
523 // get edge stop index
524 const auto edgeStopIndex = getEdgeStopIndex();
525 // take all stops/waypoints with index = -1
526 for (const auto& edgeStop : edgeStopIndex) {
527 if (edgeStop.stopIndex == -1) {
528 for (const auto& stop : edgeStop.stops) {
529 invalidStops.push_back(stop);
530 }
531 }
532 }
533 return invalidStops;
534 } else {
535 return {};
536 }
537}
538
539
540void
542 // get two points
543 const Position posA = element->getParentJunctions().front()->getPositionInView();
544 const Position posB = element->getParentJunctions().back()->getPositionInView();
545 const double rot = ((double)atan2((posB.x() - posA.x()), (posA.y() - posB.y())) * (double) 180.0 / (double)M_PI);
546 const double len = posA.distanceTo2D(posB);
547 // push draw matrix
549 // Start with the drawing of the area traslating matrix to origin
550 drawInLayer(element->getType() + 0.1);
551 // set trip color
553 // draw line
554 GLHelper::drawBoxLine(posA, rot, len, 0.25);
555 // pop draw matrix
557}
558
559
560void
561GNEDemandElement::drawStackLabel(const int number, const std::string& element, const Position& position, const double rotation,
562 const double width, const double length, const double exaggeration) const {
563 // declare contour width
564 const double contourWidth = (0.05 * exaggeration);
565 // Push matrix
567 // Traslate to top
568 glTranslated(position.x(), position.y(), GLO_VEHICLELABELS);
569 glRotated(rotation, 0, 0, -1);
570 glTranslated((width * exaggeration * 0.5) + (0.35 * exaggeration) + 0.05, 0, 0);
571 // draw external box
573 GLHelper::drawBoxLine(Position(), 0, (length * exaggeration), 0.3 * exaggeration);
574 // draw internal box
575 glTranslated(0, 0, 0.1);
576 GLHelper::setColor(RGBColor(0, 128, 0));
577 GLHelper::drawBoxLine(Position(0, -contourWidth), Position(0, -contourWidth), 0, (length * exaggeration) - (contourWidth * 2), (0.3 * exaggeration) - contourWidth);
578 // draw stack label
579 GLHelper::drawText(element + "s stacked: " + toString(number), Position(0, length * exaggeration * -0.5), (.1 * exaggeration), (0.6 * exaggeration), RGBColor::WHITE, 90, 0, -1);
580 // pop draw matrix
582}
583
584
585void
586GNEDemandElement::replaceParentEdges(const std::string& value) {
587 auto newEdges = parse<GNEHierarchicalContainerParents<GNEEdge*> >(getNet(), value);
589}
590
591
592void
594 auto newLane = myNet->getAttributeCarriers()->retrieveLane(value);
595 GNEHierarchicalElement::updateParent(this, 0, newLane);
596}
597
598
599void
601 auto newJunction = myNet->getAttributeCarriers()->retrieveJunction(value);
602 GNEHierarchicalElement::updateParent(this, 0, newJunction);
603}
604
605
606void
608 auto newJunction = myNet->getAttributeCarriers()->retrieveJunction(value);
609 GNEHierarchicalElement::updateParent(this, (int)getParentJunctions().size() - 1, newJunction);
610}
611
612
613void
615 auto newEdge = myNet->getAttributeCarriers()->retrieveEdge(value);
616 GNEHierarchicalElement::updateParent(this, 0, newEdge);
617}
618
619
620void
622 auto newEdge = myNet->getAttributeCarriers()->retrieveEdge(value);
623 GNEHierarchicalElement::updateParent(this, (int)getParentEdges().size() - 1, newEdge);
624}
625
626
627void
629 auto newAdditional = myNet->getAttributeCarriers()->retrieveAdditional(tag, value);
630 GNEHierarchicalElement::updateParent(this, 0, newAdditional);
631}
632
633
634void
636 auto newAdditional = myNet->getAttributeCarriers()->retrieveAdditional(tag, value);
637 GNEHierarchicalElement::updateParent(this, (int)getParentAdditionals().size() - 1, newAdditional);
638}
639
640
641void
642GNEDemandElement::replaceDemandElementParent(const std::vector<SumoXMLTag> tags, const std::string& value, const int parentIndex) {
643 GNEDemandElement* newDemandElement = nullptr;
644 // search demand element
645 for (auto it = tags.begin(); (it != tags.end()) && (newDemandElement == nullptr); it++) {
646 newDemandElement = myNet->getAttributeCarriers()->retrieveDemandElement(*it, value, false);
647 }
648 if (newDemandElement) {
649 GNEHierarchicalElement::updateParent(this, parentIndex, newDemandElement);
650 } else {
651 throw ProcessError("Attempted to replace with non-existant demand element " + value);
652 }
653}
654
655
656bool
658 // throw exception because this function mus be implemented in child (see GNEE3Detector)
659 throw ProcessError(StringUtils::format("Calling non-implemented function checkChildDemandElementRestriction during saving of %. It muss be reimplemented in child class", getTagStr()));
660}
661
662
663std::vector<GNEDemandElement::EdgeStopIndex>
665 std::vector<GNEDemandElement::EdgeStopIndex> edgeStopIndex;
666 // first check that this stop has parent
667 if (getParentDemandElements().size() > 0) {
668 // get path edges depending of parent
669 std::vector<GNEEdge*> pathEdges;
670 // get parent demand element
671 const auto parent = getParentDemandElements().front();
672 // continue depending of parent
673 if (parent->getTagProperty()->hasAttribute(SUMO_ATTR_EDGES)) {
674 pathEdges = parent->getParentEdges();
675 } else if (parent->getTagProperty()->vehicleRoute()) {
676 // get route edges
677 if (parent->getParentDemandElements().size() > 1) {
678 pathEdges = parent->getParentDemandElements().at(1)->getParentEdges();
679 }
680 } else if (parent->getTagProperty()->vehicleRouteEmbedded()) {
681 // get embedded route edges
682 pathEdges = parent->getChildDemandElements().front()->getParentEdges();
683 } else {
684 // get last parent edge
685 const auto lastEdge = parent->getParentEdges().back();
686 bool stop = false;
687 const auto& pathElementSegments = myNet->getDemandPathManager()->getPathElementSegments(parent);
688 // extract all edges from pathElement parent
689 for (auto it = pathElementSegments.begin(); (it != pathElementSegments.end()) && !stop; it++) {
690 if ((*it)->getLane()) {
691 pathEdges.push_back((*it)->getLane()->getParentEdge());
692 // stop if path correspond to last edge
693 if (pathEdges.back() == lastEdge) {
694 stop = true;
695 }
696 }
697 }
698 }
699 // get all parent's stops and waypoints sorted by position
700 for (const auto& demandElement : parent->getChildDemandElements()) {
701 if (demandElement->getTagProperty()->isVehicleStop()) {
702 // get stop/waypoint edge
703 GNEEdge* edge = nullptr;
704 if (demandElement->getParentAdditionals().size() > 0) {
705 edge = demandElement->getParentAdditionals().front()->getParentLanes().front()->getParentEdge();
706 } else {
707 edge = demandElement->getParentLanes().front()->getParentEdge();
708 }
709 // check if add a new edgeStopIndex or update last
710 if ((edgeStopIndex.size() > 0) && (edgeStopIndex.back().edge == edge)) {
711 edgeStopIndex.back().stops.push_back(demandElement);
712 } else {
713 edgeStopIndex.push_back(EdgeStopIndex(edge, demandElement));
714 }
715 }
716 }
717 // declare index for current stop
718 int currentEdgeStopIndex = 0;
719 for (int i = 0; (i < (int)pathEdges.size()) && (currentEdgeStopIndex < (int)edgeStopIndex.size()); i++) {
720 // check if current edge stop index is in the path
721 if (edgeStopIndex[currentEdgeStopIndex].edge == pathEdges.at(i)) {
722 edgeStopIndex[currentEdgeStopIndex].stopIndex = i;
723 currentEdgeStopIndex++;
724 } else {
725 // check if edge exist in the rest of the path
726 bool next = false;
727 for (int j = (i + 1); j < (int)pathEdges.size(); j++) {
728 if (edgeStopIndex[currentEdgeStopIndex].edge == pathEdges.at(j)) {
729 next = true;
730 }
731 }
732 if (!next) {
733 // ignore current stops (because is out of path)
734 currentEdgeStopIndex++;
735 }
736 }
737 }
738 }
739 // sort stops by position
740 for (auto& edgeStop : edgeStopIndex) {
741 if (edgeStop.stops.size() > 1) {
742 // copy all stops to a map to sort it by endPos
743 std::map<double, std::vector<GNEDemandElement*> > sortedStops;
744 for (const auto& stop : edgeStop.stops) {
745 if (sortedStops.count(stop->getAttributeDouble(SUMO_ATTR_ENDPOS)) == 0) {
746 sortedStops[stop->getAttributeDouble(SUMO_ATTR_ENDPOS)] = {stop};
747 } else {
748 sortedStops[stop->getAttributeDouble(SUMO_ATTR_ENDPOS)].push_back(stop);
749 }
750 }
751 // update stops with sorted stops
752 edgeStop.stops.clear();
753 for (const auto& sortedStop : sortedStops) {
754 edgeStop.stops.insert(edgeStop.stops.end(), sortedStop.second.begin(), sortedStop.second.end());
755 }
756 }
757 }
758 return edgeStopIndex;
759}
760
761
764 // set color depending of color active
765 switch (c.getActive()) {
766 case 0: {
767 // test for emergency vehicle
768 if (getTypeParent()->getAttribute(SUMO_ATTR_GUISHAPE) == "emergency") {
769 return RGBColor::WHITE;
770 }
771 // test for firebrigade
772 if (getTypeParent()->getAttribute(SUMO_ATTR_GUISHAPE) == "firebrigade") {
773 return RGBColor::RED;
774 }
775 // test for police car
776 if (getTypeParent()->getAttribute(SUMO_ATTR_GUISHAPE) == "police") {
777 return RGBColor::BLUE;
778 }
779 if (getTypeParent()->getAttribute(SUMO_ATTR_GUISHAPE) == "scooter") {
780 return RGBColor::WHITE;
781 }
782 // check if color was set
783 if (parameters->wasSet(VEHPARS_COLOR_SET)) {
784 return parameters->color;
785 } else {
786 // take their parent's color)
787 return getTypeParent()->getColor();
788 }
789 }
790 case 2: {
791 if (parameters->wasSet(VEHPARS_COLOR_SET)) {
792 return parameters->color;
793 } else {
794 return c.getScheme().getColor(0);
795 }
796 }
797 case 3: {
799 return getTypeParent()->getColor();
800 } else {
801 return c.getScheme().getColor(0);
802 }
803 }
804 case 4: {
806 return getRouteParent()->getColor();
807 } else {
808 return c.getScheme().getColor(0);
809 }
810 }
811 case 5: {
812 Position p = getRouteParent()->getParentEdges().at(0)->getChildLanes().at(0)->getLaneShape()[0];
813 const Boundary& b = myNet->getBoundary();
814 Position center = b.getCenter();
815 double hue = 180. + atan2(center.x() - p.x(), center.y() - p.y()) * 180. / M_PI;
816 double sat = p.distanceTo(center) / center.distanceTo(Position(b.xmin(), b.ymin()));
817 return RGBColor::fromHSV(hue, sat, 1.);
818 }
819 case 6: {
820 Position p = getRouteParent()->getParentEdges().back()->getChildLanes().at(0)->getLaneShape()[-1];
821 const Boundary& b = myNet->getBoundary();
822 Position center = b.getCenter();
823 double hue = 180. + atan2(center.x() - p.x(), center.y() - p.y()) * 180. / M_PI;
824 double sat = p.distanceTo(center) / center.distanceTo(Position(b.xmin(), b.ymin()));
825 return RGBColor::fromHSV(hue, sat, 1.);
826 }
827 case 7: {
828 Position pb = getRouteParent()->getParentEdges().at(0)->getChildLanes().at(0)->getLaneShape()[0];
829 Position pe = getRouteParent()->getParentEdges().back()->getChildLanes().at(0)->getLaneShape()[-1];
830 const Boundary& b = myNet->getBoundary();
831 double hue = 180. + atan2(pb.x() - pe.x(), pb.y() - pe.y()) * 180. / M_PI;
832 Position minp(b.xmin(), b.ymin());
833 Position maxp(b.xmax(), b.ymax());
834 double sat = pb.distanceTo(pe) / minp.distanceTo(maxp);
835 return RGBColor::fromHSV(hue, sat, 1.);
836 }
837 case 35: { // color randomly (by pointer hash)
838 std::hash<const GNEDemandElement*> ptr_hash;
839 const double hue = (double)(ptr_hash(this) % 360); // [0-360]
840 const double sat = (double)((ptr_hash(this) / 360) % 67) / 100. + 0.33; // [0.33-1]
841 return RGBColor::fromHSV(hue, sat, 1.);
842 }
843 default: {
844 return c.getScheme().getColor(0);
845 }
846 }
847}
848
849
850void
852 std::vector<GNEEdge*> edges;
853 if (myTagProperty->isRoute()) {
854 edges = getParentEdges();
855 } else if (myTagProperty->vehicleRoute()) {
856 edges = getParentDemandElements().at(1)->getParentEdges();
857 } else if (myTagProperty->vehicleRouteEmbedded()) {
858 edges = getChildDemandElements().front()->getParentEdges();
859 } else if (myTagProperty->vehicleEdges()) {
860 edges = getParentEdges();
861 }
862 // calculate path
864 // check path size
865 if (path.size() > 0) {
866 double length = 0;
867 for (const auto& edge : path) {
868 length += edge->getNBEdge()->getFinalLength();
869 }
870 for (int i = 0; i < ((int)path.size() - 1); i++) {
871 length += path.at(i)->getChildLanes().front()->getLane2laneConnections().getLane2laneGeometry(path.at(i + 1)->getChildLanes().front()).getShape().length();
872 }
873 GUIDesigns::buildFXMenuCommand(ret, TL("Route length: ") + toString(length), nullptr, ret, MID_COPY_NAME);
874 }
875}
876
877
878void
880 // create menu pane for transform operations
881 FXMenuPane* transformOperation = new FXMenuPane(ret);
882 ret->insertMenuPaneChild(transformOperation);
883 auto reverseMenuCascade = new FXMenuCascade(ret, TL("reverse"), nullptr, transformOperation);
884 // build menu commands
885 GUIDesigns::buildFXMenuCommand(transformOperation, TLF("reverse current %", myTagProperty->getTagStr()), nullptr, myNet->getViewNet(), MID_GNE_REVERSE);
886 GUIDesigns::buildFXMenuCommand(transformOperation, TLF("Add reverse %", myTagProperty->getTagStr()), nullptr, myNet->getViewNet(), MID_GNE_ADDREVERSE);
887 // check if reverse can be added
888 if (GNERouteHandler::canReverse(this)) {
889 reverseMenuCascade->enable();
890 } else {
891 reverseMenuCascade->disable();
892 }
893}
894
895/****************************************************************************/
@ DEMAND_PERSONPLAN
Mode for editing person plan.
@ DEMAND_CONTAINER
Mode for editing container.
@ DEMAND_DELETE
mode for deleting demand elements
@ DEMAND_PERSON
Mode for editing person.
@ DEMAND_SELECT
mode for selecting demand elements
@ DEMAND_MOVE
mode for moving demand elements
@ DEMAND_CONTAINERPLAN
Mode for editing container plan.
@ MID_GNE_ADDREVERSE
add reverse element
@ MID_GNE_REVERSE
reverse current element
@ MID_OPEN_ADDITIONAL_DIALOG
open additional dialog (used in netedit)
Definition GUIAppEnum.h:471
@ MID_COPY_NAME
Copy object name - popup entry.
Definition GUIAppEnum.h:455
@ GLO_VEHICLELABELS
stack and flow labels (used in netedit)
#define TL(string)
Definition MsgHandler.h:304
#define TLF(string,...)
Definition MsgHandler.h:306
const long long int VEHPARS_COLOR_SET
SumoXMLTag
Numbers representing SUMO-XML - element names.
@ SUMO_TAG_ROUTE
description of a route
@ GNE_TAG_ROUTE_EMBEDDED
embedded route
SumoXMLAttr
Numbers representing SUMO-XML - attributes.
@ SUMO_ATTR_ENDPOS
@ SUMO_ATTR_EDGES
the edges of a route
@ SUMO_ATTR_GUISHAPE
@ SUMO_ATTR_COLOR
A color information.
@ SUMO_ATTR_ID
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
Position getCenter() const
Returns the center of the boundary.
Definition Boundary.cpp:109
double ymin() const
Returns minimum y-coordinate.
Definition Boundary.cpp:127
double xmin() const
Returns minimum x-coordinate.
Definition Boundary.cpp:115
double ymax() const
Returns maximum y-coordinate.
Definition Boundary.cpp:133
double xmax() const
Returns maximum x-coordinate.
Definition Boundary.cpp:121
void removeElement(const bool isTemplate)
remove element
void addElement(const bool isTemplate)
function related with Elements
static void setColor(const RGBColor &c)
Sets the gl-color to this value.
Definition GLHelper.cpp:649
static void popMatrix()
pop matrix
Definition GLHelper.cpp:131
static void drawBoxLine(const Position &beg, double rot, double visLength, double width, double offset=0)
Draws a thick line.
Definition GLHelper.cpp:296
static void pushMatrix()
push matrix
Definition GLHelper.cpp:118
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:742
GNEApplicationWindowHelper::FileBucketHandler * getFileBucketHandler() const
get file bucket handler
bool isAttributeCarrierSelected() const
check if attribute carrier is selected
void markForDrawingFront()
mark for drawing front
FXIcon * getACIcon() const
get FXIcon associated to this AC
bool mySelected
boolean to check if this AC is selected (more quickly as checking GUIGlObjectStorage)
FileBucket * myFileBucket
filebucket vinculated whith this AC
const std::string getID() const override
get ID (all Attribute Carriers have one)
PositionVector getCommonAttributePositionVector(SumoXMLAttr key) const
void unselectAttributeCarrier()
unselect attribute carrier using GUIGlobalSelection
virtual bool isAttributeEnabled(SumoXMLAttr key) const
const std::string & getTagStr() const
get tag assigned to this object in string format
bool isTemplate() const
check if this AC is template
void drawInLayer(const double typeOrLayer, const double extraOffset=0) const
draw element in the given layer, or in front if corresponding flag is enabled
Position getCommonAttributePosition(SumoXMLAttr key) const
const GNETagProperties * getTagProperty() const
get tagProperty associated with this Attribute Carrier
GNENet * myNet
pointer to net
GNENet * getNet() const
get pointer to net
virtual void updateGeometry()=0
update pre-computed geometry information
virtual std::string getAttribute(SumoXMLAttr key) const =0
const GNETagProperties * myTagProperty
reference to tagProperty associated with this attribute carrier
GNEPlanSelector * getPlanSelector() const
get containerPlan selector
GNEPlanSelector * getPlanSelector() const
get containerPlan selector
void buildMenuCommandRouteLength(GUIGLObjectPopupMenu *ret) const
build menu command route length
bool checkDrawFromContour() const override
check if draw from contour (green)
bool isGLObjectLocked() const override
check if element is locked
Position getAttributePosition(SumoXMLAttr key) const override
std::vector< GNEDemandElement * > getInvalidStops() const
get invalid stops
virtual SUMOVehicleClass getVClass() const =0
obtain VClass related with this demand element
void updateDemandElementGeometry(const GNELane *lane, const double posOverLane)
update element stacked geometry (stacked)
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
GNEHierarchicalElement * getHierarchicalElement() override
methods to retrieve the elements linked to this GNEDemandElement
GUIGeometry myDemandElementGeometry
demand element geometry (also called "stacked geometry")
void changeFileBucket(FileBucket *fileBucket)
change filebucket manually (used only during calibratorFlows creation)
bool isValidDemandElementID(const std::string &value) const
check if a new demand element ID is valid
void selectGLObject() override
select element
GNEDemandElement * getNextChildDemandElement(const GNEDemandElement *demandElement) const
get next child demand element to the given demand element
void updateDemandElementStackLabel(const int stack)
update stack label
bool checkDrawDeleteContour() const override
check if draw delete contour (pink/white)
void replaceLastParentEdge(const std::string &value)
replace the last parent edge
void drawJunctionLine(const GNEDemandElement *element) const
draw line between junctions
virtual const RGBColor & getColor() const =0
get color
bool isPathElementSelected() const override
check if path element is selected
GUIParameterTableWindow * getParameterWindow(GUIMainWindow &app, GUISUMOAbstractView &parent) override
Returns an own parameter window.
void replaceFirstParentAdditional(SumoXMLTag tag, const std::string &value)
replace the first parent additional
GNEDemandElement * getRouteParent() const
get route parent (always the second parent demand element)
void setDemandElementID(const std::string &newID)
set demand element id
PositionVector getAttributePositionVector(SumoXMLAttr key) const override
bool checkDrawMoveContour() const override
check if draw move contour (red)
GUIGeometry mySpreadGeometry
demand element spread geometry (Only used by vehicles and pedestrians)
void buildMenuAddReverse(GUIGLObjectPopupMenu *ret) const
build menu command route length
void updateGLObject() override
update GLObject (geometry, ID, etc.)
void replaceFirstParentJunction(const std::string &value)
replace the first parent junction
std::vector< EdgeStopIndex > getEdgeStopIndex() const
get edgeStopIndex
bool checkDrawSelectContour() const override
check if draw select contour (blue)
GNEDemandElement * getTypeParent() const
get type parent (needed because first parent can be either type or typeDistribution)
void replaceDemandElementParent(const std::vector< SumoXMLTag > tags, const std::string &value, const int parentIndex)
replace demand element parent
void deleteGLObject() override
delete element
void replaceParentEdges(const std::string &value)
all edges
virtual GUIGLObjectPopupMenu * getPopUpMenu(GUIMainWindow &app, GUISUMOAbstractView &parent) override
Returns an own popup-menu.
void replaceFirstParentEdge(const std::string &value)
replace the first parent edge
int myStackedLabelNumber
stacked label number
FileBucket * getFileBucket() const override
get reference to fileBucket in which save this AC
void updateDemandElementSpreadGeometry(const GNELane *lane, const double posOverLane)
update element spread geometry
virtual Position getPositionInView() const =0
Returns position of demand element in view.
RGBColor getColorByScheme(const GUIColorer &c, const SUMOVehicleParameter *parameters) const
get color by scheme (used by vehicles, persons and containers)
const GUIGeometry & getDemandElementGeometry()
get demand element geometry (stacked)
virtual bool checkChildDemandElementRestriction() const
check restriction with the number of children
GUIGlObject * getGUIGlObject() override
get GUIGlObject associated with this GNEDemandElement
bool checkDrawRelatedContour() const override
check if draw related contour (cyan)
GNEDemandElement * getPreviousChildDemandElement(const GNEDemandElement *demandElement) const
get previous child demand element to the given demand element
void replaceFirstParentLane(const std::string &value)
replace the first parent lane
bool checkDrawDeleteContourSmall() const override
check if draw delete contour small (pink/white)
void replaceLastParentAdditional(SumoXMLTag tag, const std::string &value)
replace the last parent additional
virtual ~GNEDemandElement()
Destructor.
virtual void openDemandElementDialog()
open DemandElement Dialog
void replaceLastParentJunction(const std::string &value)
replace the last parent junction
bool checkDrawToContour() const override
check if draw from contour (magenta)
void markAsFrontElement() override
mark element as front element
bool checkDrawOverContour() const override
check if draw over contour (orange)
const GNEHierarchicalContainerParents< GNEAdditional * > & getParentAdditionals() const
get parent additionals
const GNEHierarchicalContainerParents< GNEDemandElement * > & getParentDemandElements() const
get parent demand elements
const GNEHierarchicalContainerParents< GNEEdge * > & getParentEdges() const
get parent edges
const GNEHierarchicalContainerParents< GNEJunction * > & getParentJunctions() const
get parent junctions
const GNEHierarchicalContainerParents< GNELane * > & getParentLanes() const
get parent lanes
static void updateParent(ElementType element, const int index, ParentType newParent)
update single parent element
const GNEHierarchicalContainerChildren< GNEDemandElement * > & getChildDemandElements() const
return child demand elements
static void updateParents(ElementType element, GNEHierarchicalContainerParents< ParentType > newParents)
update all parent elements
const PositionVector & getLaneShape() const
get elements shape
Definition GNELane.cpp:232
GNELane * retrieveLane(const std::string &id, bool hardFail=true, bool checkVolatileChange=false) const
get lane by id
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
GNEDemandElement * retrieveDemandElements(const std::vector< SumoXMLTag > types, const std::string &id, bool hardFail=true) const
Returns the named demand element.
void updateDemandElementID(GNEDemandElement *demandElement, const std::string &newID)
update demand element ID in container
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.
void requireSaveAdditionals()
inform that additionals has to be saved
void requireSaveDemandElements()
inform that demand elements has to be saved
GNENetHelper::SavingStatus * getSavingStatus() const
get saving status
Definition GNENet.cpp:186
void deleteDemandElement(GNEDemandElement *demandElement, GNEUndoList *undoList)
remove demand element
Definition GNENet.cpp:770
const Boundary & getBoundary() const
returns the bounder of the network
Definition GNENet.cpp:210
GNEPathManager * getDemandPathManager()
get demand path manager
Definition GNENet.cpp:198
GNENetHelper::AttributeCarriers * getAttributeCarriers() const
get all attribute carriers used in this net
Definition GNENet.cpp:174
GNEApplicationWindow * getGNEApplicationWindow() const
get tag properties database
Definition GNENet.cpp:138
GNEViewParent * getViewParent() const
get view parent (used for simplify code)
Definition GNENet.cpp:150
GNEUndoList * getUndoList() const
get undo list(used for simplify code)
Definition GNENet.cpp:156
GNEViewNet * getViewNet() const
get view net (used for simplify code)
Definition GNENet.cpp:144
bool isRoute() const
check if pathElement is a route
std::vector< GNEEdge * > calculateDijkstraPath(const SUMOVehicleClass vClass, const std::vector< GNEEdge * > &edges) const
calculate Dijkstra path between a list of edges (for example, from-via-to edges)
PathCalculator * getPathCalculator()
obtain instance of PathCalculator
const std::vector< GNESegment * > & getPathElementSegments(GNEPathElement *pathElement) const
get path segments
GNEPlanSelector * getPlanSelector() const
get personPlan selector
GNEPlanSelector * getPlanSelector() const
get personPlan selector
static bool canReverse(const GNEDemandElement *element)
reverse functions
void updateInformationLabel()
update information label
SelectionInformation * getSelectionInformation() const
get modul for selection information
bool isContainer() const
return true if tag correspond to a container element
bool isPlan() const
plans
const std::string & getTagStr() const
get Tag vinculated with this attribute Property in String Format (used to avoid multiple calls to toS...
bool isRoute() const
return true if tag correspond to a route element
bool isVehicle() const
return true if tag correspond to a vehicle element
SumoXMLTag getTag() const
get Tag vinculated with this attribute Property
bool vehicleRouteEmbedded() const
return true if tag correspond to a vehicle placed over an embedded route
bool hasDialog() const
return true if tag correspond to an element that can be edited using a dialog
bool saveInParentFile() const
element is saved in the parent file
bool vehicleEdges() const
return true if tag correspond to a vehicle placed over from-to edges
const std::vector< const GNEAttributeProperties * > & getAttributeProperties() const
get all attribute properties
bool hasAttribute(SumoXMLAttr attr) const
check if current TagProperties owns the attribute "attr"
bool isVehicleStop() const
return true if tag correspond to a vehicle stop element
bool isPerson() const
return true if tag correspond to a person element
bool vehicleRoute() const
plan parents
GNEAttributeCarrier * getCurrentTemplateAC() const
get current templateAC
GNETagSelector * getVehicleTagSelector() const
get vehicle tag selector (needed for transform vehicles)
const std::unordered_set< GNEAttributeCarrier * > & getACs() const
get hash table with all inspected ACs
bool isObjectLocked(GUIGlObjectType objectType, const bool selected) const
check if given GLObject is locked for inspect, select, delete and move
GNEAttributeCarrier * getAttributeCarrierFront() const
get front attribute carrier or a pointer to nullptr
const GUIGlObject * getGUIGlObjectFront() const
get front GUIGLObject or a pointer to nullptr
GNEDemandElement * getDemandElementFront() const
get front demand element or a pointer to nullptr
bool isCurrentlyMovingElements() const
check if an element is being moved
const GNEViewNetHelper::EditModes & getEditModes() const
get edit modes
GNEViewNetHelper::InspectedElements & getInspectedElements()
get inspected elements
bool checkOverLockedElement(const GUIGlObject *GLObject, const bool isSelected) const
check if given element is locked (used for drawing select and delete contour)
const GNEViewNetHelper::ViewObjectsSelector & getViewObjectsSelector() const
get objects under cursor
GNEViewNetHelper::LockManager & getLockManager()
get lock manager
GNEPersonPlanFrame * getPersonPlanFrame() const
get frame for DEMAND_PERSONFRAME
GNESelectorFrame * getSelectorFrame() const
get frame for select elements
GNEContainerPlanFrame * getContainerPlanFrame() const
get frame for DEMAND_CONTAINERFRAME
GNEVehicleFrame * getVehicleFrame() const
get frame for DEMAND_VEHICLE
GNEContainerFrame * getContainerFrame() const
get frame for DEMAND_CONTAINER
GNEPersonFrame * getPersonFrame() const
get frame for DEMAND_PERSON
static FXMenuCommand * buildFXMenuCommand(FXComposite *p, const std::string &text, FXIcon *icon, FXObject *tgt, FXSelector sel, const bool disable=false)
build menu command
The popup menu of a globject.
void insertMenuPaneChild(FXMenuPane *child)
Insert a sub-menu pane in this GUIGLObjectPopupMenu.
GUIGlObject * getGLObject() const
The object that belongs to this popup-menu.
void updateGeometry(const PositionVector &shape)
update entire geometry
virtual void setMicrosimID(const std::string &newID)
Changes the microsimID of the object.
GUIGlObjectType getType() const
Returns the type of the object as coded in GUIGlObjectType.
void buildPopUpMenuCommonOptions(GUIGLObjectPopupMenu *ret, GUIMainWindow &app, GUISUMOAbstractView *parent, const SumoXMLTag tag, const bool selected, bool addSeparator=true)
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.
T getColor(const double value) const
GUIGLObjectPopupMenu * getPopup() const
ge the current popup-menu
A point in 2D or 3D with translation and scaling methods.
Definition Position.h:37
double distanceTo2D(const Position &p2) const
returns the euclidean distance in the x-y-plane
Definition Position.h:273
double distanceTo(const Position &p2) const
returns the euclidean distance in 3 dimensions
Definition Position.h:263
double x() const
Returns the x-position.
Definition Position.h:52
double y() const
Returns the y-position.
Definition Position.h:57
A list of positions.
static const RGBColor WHITE
Definition RGBColor.h:195
static const RGBColor BLUE
Definition RGBColor.h:190
static const RGBColor GREY
Definition RGBColor.h:197
static RGBColor fromHSV(double h, double s, double v)
Converts the given hsv-triplet to rgb, inspired by http://alvyray.com/Papers/CG/hsv2rgb....
Definition RGBColor.cpp:403
static const RGBColor DEFAULT_COLOR
The default color (for vehicle types and vehicles)
Definition RGBColor.h:202
static const RGBColor RED
named colors
Definition RGBColor.h:188
Structure representing possible vehicle parameter.
bool wasSet(long long int what) const
Returns whether the given parameter was set.
RGBColor color
The vehicle's color, TraCI may change this.
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 isCurrentSupermodeDemand() const
@check if current supermode is Demand