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
28#include <netedit/GNENet.h>
29#include <netedit/GNESegment.h>
36
37#include "GNEDemandElement.h"
38#include "GNERouteHandler.h"
39
40// ===========================================================================
41// member method definitions
42// ===========================================================================
43#ifdef _MSC_VER
44#pragma warning(push)
45#pragma warning(disable: 4355) // mask warning about "this" in initializers
46#endif
47GNEDemandElement::GNEDemandElement(const std::string& id, GNENet* net, const std::string& filename,
48 SumoXMLTag tag, const GNEPathElement::Options pathOptions) :
49 GNEAttributeCarrier(tag, net, filename, id.empty()),
50 GUIGlObject(net->getTagPropertiesDatabase()->getTagProperty(tag, true)->getGLType(), id,
51 GUIIconSubSys::getIcon(net->getTagPropertiesDatabase()->getTagProperty(tag, true)->getGUIIcon())),
52 GNEPathElement(pathOptions),
53 myStackedLabelNumber(0) {
54}
55
56
58 const GNEPathElement::Options pathOptions) :
59 GNEAttributeCarrier(tag, demandElementParent->getNet(), demandElementParent->getFilename(), false),
60 GUIGlObject(demandElementParent->getNet()->getTagPropertiesDatabase()->getTagProperty(tag, true)->getGLType(), demandElementParent->getID(),
61 GUIIconSubSys::getIcon(demandElementParent->getNet()->getTagPropertiesDatabase()->getTagProperty(tag, true)->getGUIIcon())),
62 GNEPathElement(pathOptions),
63 myStackedLabelNumber(0) {
64}
65#ifdef _MSC_VER
66#pragma warning(pop)
67#endif
68
70
71
76
77
80 return this;
81}
82
83
84const GUIGlObject*
86 return this;
87}
88
89
90const GUIGeometry&
94
95
98 // first check if there are demand elements
99 if (getChildDemandElements().empty()) {
100 return nullptr;
101 } else {
102 // find child demand element
103 auto it = std::find(getChildDemandElements().begin(), getChildDemandElements().end(), demandElement);
104 // return element or null depending of iterator
105 if (it == getChildDemandElements().end()) {
106 // in this case, we assume that the last child is the previos child
107 return getChildDemandElements().back();
108 } else if (it == getChildDemandElements().begin()) {
109 return nullptr;
110 } else {
111 return *(it - 1);
112 }
113 }
114}
115
116
119 // find child demand element
120 auto it = std::find(getChildDemandElements().begin(), getChildDemandElements().end(), demandElement);
121 // return element or null depending of iterator
122 if (it == getChildDemandElements().end()) {
123 return nullptr;
124 } else if (it == (getChildDemandElements().end() - 1)) {
125 return nullptr;
126 } else {
127 return *(it + 1);
128 }
129}
130
131
132void
133GNEDemandElement::updateDemandElementGeometry(const GNELane* lane, const double posOverLane) {
134 myDemandElementGeometry.updateGeometry(lane->getLaneShape(), posOverLane, /*myMovingLateralOffset*/ 0);
135}
136
137
138void
142
143
144void
145GNEDemandElement::updateDemandElementSpreadGeometry(const GNELane* lane, const double posOverLane) {
146 mySpreadGeometry.updateGeometry(lane->getLaneShape(), posOverLane, /*myMovingLateralOffset*/ 0);
147}
148
149
150const GUIGeometry&
154
155
156bool
158 return false;
159}
160
161
162bool
164 return false;
165}
166
167
168bool
171 // check if inspected parent is inspected
172 for (const auto& inspectedAC : myNet->getViewNet()->getInspectedElements().getACs()) {
173 if (inspectedAC->getTagProperty()->vehicleRouteEmbedded()) {
174 const auto demandElement = dynamic_cast<GNEDemandElement*>(inspectedAC);
175 if (demandElement && (demandElement->getChildDemandElements().size() > 0) &&
176 (demandElement->getChildDemandElements().at(0) == this)) {
177 return true;
178 }
179 }
180 }
181 }
182 // check opened popup
183 if (myNet->getViewNet()->getPopup()) {
184 return myNet->getViewNet()->getPopup()->getGLObject() == this;
185 }
186 return false;
187}
188
189
190bool
192 // get modes
193 const auto& modes = myNet->getViewNet()->getEditModes();
194 // get frames
195 const auto& personFramePlanSelector = myNet->getViewNet()->getViewParent()->getPersonFrame()->getPlanSelector();
196 const auto& personPlanFramePlanSelector = myNet->getViewNet()->getViewParent()->getPersonPlanFrame()->getPlanSelector();
197 const auto& containerFramePlanSelector = myNet->getViewNet()->getViewParent()->getContainerFrame()->getPlanSelector();
198 const auto& containerPlanFramePlanSelector = myNet->getViewNet()->getViewParent()->getContainerPlanFrame()->getPlanSelector();
199 // special case for Route
201 // get vehicle frame
202 const auto& vehicleFrame = myNet->getViewNet()->getViewParent()->getVehicleFrame();
203 // check if we're in vehicle mode
204 if (vehicleFrame->shown()) {
205 // get current vehicle template
206 const auto& vehicleTemplate = vehicleFrame->getVehicleTagSelector()->getCurrentTemplateAC();
207 // check if vehicle can be placed over route
208 if (vehicleTemplate && vehicleTemplate->getTagProperty()->vehicleRoute()) {
210 }
211 } else if (modes.isCurrentSupermodeDemand()) {
212 // check if we're in person or personPlan modes
213 if (((modes.demandEditMode == DemandEditMode::DEMAND_PERSON) && personFramePlanSelector->markRoutes()) ||
214 ((modes.demandEditMode == DemandEditMode::DEMAND_PERSONPLAN) && personPlanFramePlanSelector->markRoutes()) ||
215 ((modes.demandEditMode == DemandEditMode::DEMAND_CONTAINER) && containerFramePlanSelector->markRoutes()) ||
216 ((modes.demandEditMode == DemandEditMode::DEMAND_CONTAINERPLAN) && containerPlanFramePlanSelector->markRoutes())) {
218 }
219 }
220 }
221 return false;
222}
223
224
225bool
227 // get edit modes
228 const auto& editModes = myNet->getViewNet()->getEditModes();
229 // check if we're in delete mode
230 if (editModes.isCurrentSupermodeDemand() && (editModes.demandEditMode == DemandEditMode::DEMAND_DELETE)) {
232 } else {
233 return false;
234 }
235}
236
237
238bool
242 if (route && (route == myNet->getViewNet()->getViewObjectsSelector().getAttributeCarrierFront())) {
243 return (getParentDemandElements().at(1) == route);
244 }
247 if (vehicle && (vehicle == myNet->getViewNet()->getViewObjectsSelector().getAttributeCarrierFront())) {
248 return (getParentDemandElements().front() == vehicle);
249 }
250 }
251 return false;
252}
253
254
255bool
257 // get edit modes
258 const auto& editModes = myNet->getViewNet()->getEditModes();
259 // check if we're in select mode
260 if (editModes.isCurrentSupermodeDemand() && (editModes.demandEditMode == DemandEditMode::DEMAND_SELECT)) {
262 } else {
263 return false;
264 }
265}
266
267
268bool
270 // get edit modes
271 const auto& editModes = myNet->getViewNet()->getEditModes();
272 // check first set of conditions
273 if (!myNet->getViewNet()->isCurrentlyMovingElements() && // another elements are not currently moved
274 editModes.isCurrentSupermodeDemand() && // supermode demand
275 (editModes.demandEditMode == DemandEditMode::DEMAND_MOVE) && // move mode
276 myNet->getViewNet()->checkOverLockedElement(this, mySelected) && // no locked
277 myNet->getViewNet()->getViewObjectsSelector().getGUIGlObjectFront() == this) { // first element
278 // continue depending of subtype
279 if (myTagProperty->isVehicle()) {
280 // only vehicles over edges can be moved
282 return true;
283 } else {
284 return false;
285 }
286 } else if ((myTagProperty->isPerson() || myTagProperty->isContainer()) && (getChildDemandElements().size() > 0)) {
287 // only persons/containers with their first plan over edge can be moved
288 return getChildDemandElements().front()->getTagProperty()->planFromEdge();
289 } else {
290 return false;
291 }
292 } else {
293 return false;
294 }
295}
296
297
298void
300 throw InvalidArgument(getTagStr() + " doesn't have a demand element dialog");
301}
302
303
306 // create popup
307 GUIGLObjectPopupMenu* ret = new GUIGLObjectPopupMenu(app, parent, this);
308 // build common options
310 // show option to open demand element dialog
311 if (myTagProperty->hasDialog()) {
312 GUIDesigns::buildFXMenuCommand(ret, ("Open " + getTagStr() + " Dialog").c_str(), getACIcon(), &parent, MID_OPEN_ADDITIONAL_DIALOG);
313 new FXMenuSeparator(ret);
314 }
315 GUIDesigns::buildFXMenuCommand(ret, "Cursor position in view: " + toString(getPositionInView().x()) + "," + toString(getPositionInView().y()), nullptr, nullptr, 0);
316 return ret;
317}
318
319
322 // Create table
324 // Iterate over attributes
325 for (const auto& attrProperty : myTagProperty->getAttributeProperties()) {
326 // Add attribute and set it dynamic if aren't unique
327 if (attrProperty->isUnique()) {
328 ret->mkItem(attrProperty->getAttrStr().c_str(), false, getAttribute(attrProperty->getAttr()));
329 } else {
330 ret->mkItem(attrProperty->getAttrStr().c_str(), true, getAttribute(attrProperty->getAttr()));
331 }
332 }
333 // close building
334 ret->closeBuilding();
335 return ret;
336}
337
338
339bool
347
348
349void
353
354
355void
357 // we need an special checks due hierarchies
358 if (myTagProperty->isPlan()) {
359 // get person/container plarent
360 GNEDemandElement* planParent = getParentDemandElements().front();
361 // if this is the last person/container plan element, remove parent instead plan
362 if (planParent->getChildDemandElements().size() == 1) {
363 planParent->deleteGLObject();
364 } else {
366 }
368 // remove parent demand element
369 getParentDemandElements().front()->deleteGLObject();
370 } else {
372 }
373}
374
375
376void
386
387
388void
392
393
398
399
404
405
406bool
410
411// ---------------------------------------------------------------------------
412// GNEDemandElement - protected methods
413// ---------------------------------------------------------------------------
414
415bool
416GNEDemandElement::isValidDemandElementID(const std::string& value) const {
417 if (!isTemplate() && (value == getID())) {
418 return true;
419 } else if (SUMOXMLDefinitions::isValidVehicleID(value)) {
420 return (myNet->getAttributeCarriers()->retrieveDemandElement(myTagProperty->getTag(), value, false) == nullptr);
421 } else {
422 return false;
423 }
424}
425
426
427bool
428GNEDemandElement::isValidDemandElementID(const std::vector<SumoXMLTag>& tags, const std::string& value) const {
429 if (isTemplate() && value.empty()) {
430 return true;
431 } else if (!isTemplate() && (value == getID())) {
432 return true;
433 } else if (SUMOXMLDefinitions::isValidVehicleID(value)) {
434 return (myNet->getAttributeCarriers()->retrieveDemandElements(tags, value, false) == nullptr);
435 } else {
436 return false;
437 }
438}
439
440
441void
442GNEDemandElement::setDemandElementID(const std::string& newID) {
443 // update ID
445 setMicrosimID(newID);
446 } else {
448 }
449 // check if update ids of child elements
451 // Change IDs of all person plans children (stops, embedded routes...)
452 for (const auto& childDemandElement : getChildDemandElements()) {
453 childDemandElement->setDemandElementID(getID());
454 }
455 }
456}
457
458
461 if (getParentDemandElements().size() < 1) {
462 throw InvalidArgument("This demand element doesn't have a type parent");
463 } else if ((getParentDemandElements().at(0)->getTagProperty()->isType()) ||
464 (getParentDemandElements().at(0)->getTagProperty()->isTypeDistribution())) {
465 return getParentDemandElements().at(0);
466 } else {
467 throw InvalidArgument("The first parent isn't a type");
468 }
469}
470
471
474 if (getParentDemandElements().size() < 2) {
475 throw InvalidArgument("This demand element doesn't have a route parent");
476 } else if ((getParentDemandElements().at(1)->getTagProperty()->isRoute()) ||
477 (getParentDemandElements().at(1)->getTagProperty()->isRouteDistribution())) {
478 return getParentDemandElements().at(1);
479 } else {
480 throw InvalidArgument("The second parent isn't a route");
481 }
482}
483
484
485std::vector<GNEDemandElement*>
488 // get stops
489 std::vector<GNEDemandElement*> invalidStops;
490 // get edge stop index
491 const auto edgeStopIndex = getEdgeStopIndex();
492 // take all stops/waypoints with index = -1
493 for (const auto& edgeStop : edgeStopIndex) {
494 if (edgeStop.stopIndex == -1) {
495 for (const auto& stop : edgeStop.stops) {
496 invalidStops.push_back(stop);
497 }
498 }
499 }
500 return invalidStops;
501 } else {
502 return {};
503 }
504}
505
506
507void
509 // get two points
510 const Position posA = element->getParentJunctions().front()->getPositionInView();
511 const Position posB = element->getParentJunctions().back()->getPositionInView();
512 const double rot = ((double)atan2((posB.x() - posA.x()), (posA.y() - posB.y())) * (double) 180.0 / (double)M_PI);
513 const double len = posA.distanceTo2D(posB);
514 // push draw matrix
516 // Start with the drawing of the area traslating matrix to origin
517 drawInLayer(element->getType() + 0.1);
518 // set trip color
520 // draw line
521 GLHelper::drawBoxLine(posA, rot, len, 0.25);
522 // pop draw matrix
524}
525
526
527void
528GNEDemandElement::drawStackLabel(const int number, const std::string& element, const Position& position, const double rotation,
529 const double width, const double length, const double exaggeration) const {
530 // declare contour width
531 const double contourWidth = (0.05 * exaggeration);
532 // Push matrix
534 // Traslate to top
535 glTranslated(position.x(), position.y(), GLO_VEHICLELABELS);
536 glRotated(rotation, 0, 0, -1);
537 glTranslated((width * exaggeration * 0.5) + (0.35 * exaggeration) + 0.05, 0, 0);
538 // draw external box
540 GLHelper::drawBoxLine(Position(), 0, (length * exaggeration), 0.3 * exaggeration);
541 // draw internal box
542 glTranslated(0, 0, 0.1);
543 GLHelper::setColor(RGBColor(0, 128, 0));
544 GLHelper::drawBoxLine(Position(0, -contourWidth), Position(0, -contourWidth), 0, (length * exaggeration) - (contourWidth * 2), (0.3 * exaggeration) - contourWidth);
545 // draw stack label
546 GLHelper::drawText(element + "s stacked: " + toString(number), Position(0, length * exaggeration * -0.5), (.1 * exaggeration), (0.6 * exaggeration), RGBColor::WHITE, 90, 0, -1);
547 // pop draw matrix
549}
550
551
552void
553GNEDemandElement::replaceParentEdges(const std::string& value) {
554 auto newEdges = parse<GNEHierarchicalContainerParents<GNEEdge*> >(getNet(), value);
556}
557
558
559void
561 auto newLane = myNet->getAttributeCarriers()->retrieveLane(value);
562 GNEHierarchicalElement::updateParent(this, 0, newLane);
563}
564
565
566void
568 auto newJunction = myNet->getAttributeCarriers()->retrieveJunction(value);
569 GNEHierarchicalElement::updateParent(this, 0, newJunction);
570}
571
572
573void
575 auto newJunction = myNet->getAttributeCarriers()->retrieveJunction(value);
576 GNEHierarchicalElement::updateParent(this, (int)getParentJunctions().size() - 1, newJunction);
577}
578
579
580void
582 auto newEdge = myNet->getAttributeCarriers()->retrieveEdge(value);
583 GNEHierarchicalElement::updateParent(this, 0, newEdge);
584}
585
586
587void
589 auto newEdge = myNet->getAttributeCarriers()->retrieveEdge(value);
590 GNEHierarchicalElement::updateParent(this, (int)getParentEdges().size() - 1, newEdge);
591}
592
593
594void
596 auto newAdditional = myNet->getAttributeCarriers()->retrieveAdditional(tag, value);
597 GNEHierarchicalElement::updateParent(this, 0, newAdditional);
598}
599
600
601void
603 auto newAdditional = myNet->getAttributeCarriers()->retrieveAdditional(tag, value);
604 GNEHierarchicalElement::updateParent(this, (int)getParentAdditionals().size() - 1, newAdditional);
605}
606
607
608void
609GNEDemandElement::replaceDemandElementParent(const std::vector<SumoXMLTag> tags, const std::string& value, const int parentIndex) {
610 GNEDemandElement* newDemandElement = nullptr;
611 // search demand element
612 for (auto it = tags.begin(); (it != tags.end()) && (newDemandElement == nullptr); it++) {
613 newDemandElement = myNet->getAttributeCarriers()->retrieveDemandElement(*it, value, false);
614 }
615 if (newDemandElement) {
616 GNEHierarchicalElement::updateParent(this, parentIndex, newDemandElement);
617 } else {
618 throw ProcessError("Attempted to replace with non-existant demand element " + value);
619 }
620}
621
622
623bool
625 // throw exception because this function mus be implemented in child (see GNEE3Detector)
626 throw ProcessError(StringUtils::format("Calling non-implemented function checkChildDemandElementRestriction during saving of %. It muss be reimplemented in child class", getTagStr()));
627}
628
629
630std::vector<GNEDemandElement::EdgeStopIndex>
632 std::vector<GNEDemandElement::EdgeStopIndex> edgeStopIndex;
633 // first check that this stop has parent
634 if (getParentDemandElements().size() > 0) {
635 // get path edges depending of parent
636 std::vector<GNEEdge*> pathEdges;
637 // get parent demand element
638 const auto parent = getParentDemandElements().front();
639 // continue depending of parent
640 if (parent->getTagProperty()->hasAttribute(SUMO_ATTR_EDGES)) {
641 pathEdges = parent->getParentEdges();
642 } else if (parent->getTagProperty()->vehicleRoute()) {
643 // get route edges
644 if (parent->getParentDemandElements().size() > 1) {
645 pathEdges = parent->getParentDemandElements().at(1)->getParentEdges();
646 }
647 } else if (parent->getTagProperty()->vehicleRouteEmbedded()) {
648 // get embedded route edges
649 pathEdges = parent->getChildDemandElements().front()->getParentEdges();
650 } else {
651 // get last parent edge
652 const auto lastEdge = parent->getParentEdges().back();
653 bool stop = false;
654 const auto& pathElementSegments = myNet->getDemandPathManager()->getPathElementSegments(parent);
655 // extract all edges from pathElement parent
656 for (auto it = pathElementSegments.begin(); (it != pathElementSegments.end()) && !stop; it++) {
657 if ((*it)->getLane()) {
658 pathEdges.push_back((*it)->getLane()->getParentEdge());
659 // stop if path correspond to last edge
660 if (pathEdges.back() == lastEdge) {
661 stop = true;
662 }
663 }
664 }
665 }
666 // get all parent's stops and waypoints sorted by position
667 for (const auto& demandElement : parent->getChildDemandElements()) {
668 if (demandElement->getTagProperty()->isVehicleStop()) {
669 // get stop/waypoint edge
670 GNEEdge* edge = nullptr;
671 if (demandElement->getParentAdditionals().size() > 0) {
672 edge = demandElement->getParentAdditionals().front()->getParentLanes().front()->getParentEdge();
673 } else {
674 edge = demandElement->getParentLanes().front()->getParentEdge();
675 }
676 // check if add a new edgeStopIndex or update last
677 if ((edgeStopIndex.size() > 0) && (edgeStopIndex.back().edge == edge)) {
678 edgeStopIndex.back().stops.push_back(demandElement);
679 } else {
680 edgeStopIndex.push_back(EdgeStopIndex(edge, demandElement));
681 }
682 }
683 }
684 // declare index for current stop
685 int currentEdgeStopIndex = 0;
686 for (int i = 0; (i < (int)pathEdges.size()) && (currentEdgeStopIndex < (int)edgeStopIndex.size()); i++) {
687 // check if current edge stop index is in the path
688 if (edgeStopIndex[currentEdgeStopIndex].edge == pathEdges.at(i)) {
689 edgeStopIndex[currentEdgeStopIndex].stopIndex = i;
690 currentEdgeStopIndex++;
691 } else {
692 // check if edge exist in the rest of the path
693 bool next = false;
694 for (int j = (i + 1); j < (int)pathEdges.size(); j++) {
695 if (edgeStopIndex[currentEdgeStopIndex].edge == pathEdges.at(j)) {
696 next = true;
697 }
698 }
699 if (!next) {
700 // ignore current stops (because is out of path)
701 currentEdgeStopIndex++;
702 }
703 }
704 }
705 }
706 // sort stops by position
707 for (auto& edgeStop : edgeStopIndex) {
708 if (edgeStop.stops.size() > 1) {
709 // copy all stops to a map to sort it by endPos
710 std::map<double, std::vector<GNEDemandElement*> > sortedStops;
711 for (const auto& stop : edgeStop.stops) {
712 if (sortedStops.count(stop->getAttributeDouble(SUMO_ATTR_ENDPOS)) == 0) {
713 sortedStops[stop->getAttributeDouble(SUMO_ATTR_ENDPOS)] = {stop};
714 } else {
715 sortedStops[stop->getAttributeDouble(SUMO_ATTR_ENDPOS)].push_back(stop);
716 }
717 }
718 // update stops with sorted stops
719 edgeStop.stops.clear();
720 for (const auto& sortedStop : sortedStops) {
721 edgeStop.stops.insert(edgeStop.stops.end(), sortedStop.second.begin(), sortedStop.second.end());
722 }
723 }
724 }
725 return edgeStopIndex;
726}
727
728
731 // set color depending of color active
732 switch (c.getActive()) {
733 case 0: {
734 // test for emergency vehicle
735 if (getTypeParent()->getAttribute(SUMO_ATTR_GUISHAPE) == "emergency") {
736 return RGBColor::WHITE;
737 }
738 // test for firebrigade
739 if (getTypeParent()->getAttribute(SUMO_ATTR_GUISHAPE) == "firebrigade") {
740 return RGBColor::RED;
741 }
742 // test for police car
743 if (getTypeParent()->getAttribute(SUMO_ATTR_GUISHAPE) == "police") {
744 return RGBColor::BLUE;
745 }
746 if (getTypeParent()->getAttribute(SUMO_ATTR_GUISHAPE) == "scooter") {
747 return RGBColor::WHITE;
748 }
749 // check if color was set
750 if (parameters->wasSet(VEHPARS_COLOR_SET)) {
751 return parameters->color;
752 } else {
753 // take their parent's color)
754 return getTypeParent()->getColor();
755 }
756 }
757 case 2: {
758 if (parameters->wasSet(VEHPARS_COLOR_SET)) {
759 return parameters->color;
760 } else {
761 return c.getScheme().getColor(0);
762 }
763 }
764 case 3: {
766 return getTypeParent()->getColor();
767 } else {
768 return c.getScheme().getColor(0);
769 }
770 }
771 case 4: {
773 return getRouteParent()->getColor();
774 } else {
775 return c.getScheme().getColor(0);
776 }
777 }
778 case 5: {
779 Position p = getRouteParent()->getParentEdges().at(0)->getChildLanes().at(0)->getLaneShape()[0];
780 const Boundary& b = myNet->getBoundary();
781 Position center = b.getCenter();
782 double hue = 180. + atan2(center.x() - p.x(), center.y() - p.y()) * 180. / M_PI;
783 double sat = p.distanceTo(center) / center.distanceTo(Position(b.xmin(), b.ymin()));
784 return RGBColor::fromHSV(hue, sat, 1.);
785 }
786 case 6: {
787 Position p = getRouteParent()->getParentEdges().back()->getChildLanes().at(0)->getLaneShape()[-1];
788 const Boundary& b = myNet->getBoundary();
789 Position center = b.getCenter();
790 double hue = 180. + atan2(center.x() - p.x(), center.y() - p.y()) * 180. / M_PI;
791 double sat = p.distanceTo(center) / center.distanceTo(Position(b.xmin(), b.ymin()));
792 return RGBColor::fromHSV(hue, sat, 1.);
793 }
794 case 7: {
795 Position pb = getRouteParent()->getParentEdges().at(0)->getChildLanes().at(0)->getLaneShape()[0];
796 Position pe = getRouteParent()->getParentEdges().back()->getChildLanes().at(0)->getLaneShape()[-1];
797 const Boundary& b = myNet->getBoundary();
798 double hue = 180. + atan2(pb.x() - pe.x(), pb.y() - pe.y()) * 180. / M_PI;
799 Position minp(b.xmin(), b.ymin());
800 Position maxp(b.xmax(), b.ymax());
801 double sat = pb.distanceTo(pe) / minp.distanceTo(maxp);
802 return RGBColor::fromHSV(hue, sat, 1.);
803 }
804 case 35: { // color randomly (by pointer hash)
805 std::hash<const GNEDemandElement*> ptr_hash;
806 const double hue = (double)(ptr_hash(this) % 360); // [0-360]
807 const double sat = (double)((ptr_hash(this) / 360) % 67) / 100. + 0.33; // [0.33-1]
808 return RGBColor::fromHSV(hue, sat, 1.);
809 }
810 default: {
811 return c.getScheme().getColor(0);
812 }
813 }
814}
815
816
817void
819 std::vector<GNEEdge*> edges;
820 if (myTagProperty->isRoute()) {
821 edges = getParentEdges();
822 } else if (myTagProperty->vehicleRoute()) {
823 edges = getParentDemandElements().at(1)->getParentEdges();
824 } else if (myTagProperty->vehicleRouteEmbedded()) {
825 edges = getChildDemandElements().front()->getParentEdges();
826 } else if (myTagProperty->vehicleEdges()) {
827 edges = getParentEdges();
828 }
829 // calculate path
831 // check path size
832 if (path.size() > 0) {
833 double length = 0;
834 for (const auto& edge : path) {
835 length += edge->getNBEdge()->getFinalLength();
836 }
837 for (int i = 0; i < ((int)path.size() - 1); i++) {
838 length += path.at(i)->getChildLanes().front()->getLane2laneConnections().getLane2laneGeometry(path.at(i + 1)->getChildLanes().front()).getShape().length();
839 }
840 GUIDesigns::buildFXMenuCommand(ret, TL("Route length: ") + toString(length), nullptr, ret, MID_COPY_NAME);
841 }
842}
843
844
845void
847 // create menu pane for transform operations
848 FXMenuPane* transformOperation = new FXMenuPane(ret);
849 ret->insertMenuPaneChild(transformOperation);
850 auto reverseMenuCascade = new FXMenuCascade(ret, TL("reverse"), nullptr, transformOperation);
851 // build menu commands
852 GUIDesigns::buildFXMenuCommand(transformOperation, TLF("reverse current %", myTagProperty->getTagStr()), nullptr, myNet->getViewNet(), MID_GNE_REVERSE);
853 GUIDesigns::buildFXMenuCommand(transformOperation, TLF("Add reverse %", myTagProperty->getTagStr()), nullptr, myNet->getViewNet(), MID_GNE_ADDREVERSE);
854 // check if reverse can be added
855 if (GNERouteHandler::canReverse(this)) {
856 reverseMenuCascade->enable();
857 } else {
858 reverseMenuCascade->disable();
859 }
860}
861
862/****************************************************************************/
@ 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
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
bool isAttributeCarrierSelected() const
check if attribute carrier is selected
void markForDrawingFront()
mark for drawing front
void selectAttributeCarrier()
select attribute carrier using GUIGlobalSelection
FXIcon * getACIcon() const
get FXIcon associated to this AC
bool mySelected
boolean to check if this AC is selected (more quickly as checking GUIGlObjectStorage)
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")
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
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.
A NBNetBuilder extended by visualisation and editing capabilities.
Definition GNENet.h:42
void deleteDemandElement(GNEDemandElement *demandElement, GNEUndoList *undoList)
remove demand element
Definition GNENet.cpp:746
const Boundary & getBoundary() const
returns the bounder of the network
Definition GNENet.cpp:186
GNEPathManager * getDemandPathManager()
get demand path manager
Definition GNENet.cpp:174
GNENetHelper::AttributeCarriers * getAttributeCarriers() const
get all attribute carriers used in this net
Definition GNENet.cpp:144
GNEViewNet * getViewNet() const
get view net
Definition GNENet.cpp:2193
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 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
GNEViewParent * getViewParent() const
get the net object
bool checkOverLockedElement(const GUIGlObject *GLObject, const bool isSelected) const
check if given element is locked (used for drawing select and delete contour)
GNEUndoList * getUndoList() const
get the undoList object
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