Eclipse SUMO - Simulation of Urban MObility
All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Modules Pages
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
21#include <netedit/GNENet.h>
22#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
48GNEDemandElement::GNEDemandElement(const std::string& id, GNENet* net, const std::string& filename,
49 SumoXMLTag tag, const GNEPathElement::Options pathOptions) :
50 GNEAttributeCarrier(tag, net, filename, id.empty()),
51 GUIGlObject(net->getTagPropertiesDatabase()->getTagProperty(tag, true)->getGLType(), id,
52 GUIIconSubSys::getIcon(net->getTagPropertiesDatabase()->getTagProperty(tag, true)->getGUIIcon())),
53 GNEPathElement(pathOptions),
54 myStackedLabelNumber(0) {
55}
56
57
59 const GNEPathElement::Options pathOptions) :
60 GNEAttributeCarrier(tag, demandElementParent->getNet(), demandElementParent->getFilename(), false),
61 GUIGlObject(demandElementParent->getNet()->getTagPropertiesDatabase()->getTagProperty(tag, true)->getGLType(), demandElementParent->getID(),
62 GUIIconSubSys::getIcon(demandElementParent->getNet()->getTagPropertiesDatabase()->getTagProperty(tag, true)->getGUIIcon())),
63 GNEPathElement(pathOptions),
64 myStackedLabelNumber(0) {
65}
66#ifdef _MSC_VER
67#pragma warning(pop)
68#endif
69
71
72
77
78
79void
80GNEDemandElement::removeGeometryPoint(const Position /*clickedPosition*/, GNEUndoList* /*undoList*/) {
81 // currently there isn't demand elements with removable geometry points
82}
83
84
87 return this;
88}
89
90
91const GUIGlObject*
93 return this;
94}
95
96
97const GUIGeometry&
101
102
105 // first check if there are demand elements
106 if (getChildDemandElements().empty()) {
107 return nullptr;
108 } else {
109 // find child demand element
110 auto it = std::find(getChildDemandElements().begin(), getChildDemandElements().end(), demandElement);
111 // return element or null depending of iterator
112 if (it == getChildDemandElements().end()) {
113 // in this case, we assume that the last child is the previos child
114 return getChildDemandElements().back();
115 } else if (it == getChildDemandElements().begin()) {
116 return nullptr;
117 } else {
118 return *(it - 1);
119 }
120 }
121}
122
123
126 // find child demand element
127 auto it = std::find(getChildDemandElements().begin(), getChildDemandElements().end(), demandElement);
128 // return element or null depending of iterator
129 if (it == getChildDemandElements().end()) {
130 return nullptr;
131 } else if (it == (getChildDemandElements().end() - 1)) {
132 return nullptr;
133 } else {
134 return *(it + 1);
135 }
136}
137
138
139void
143
144
145void
149
150
151void
155
156
157const GUIGeometry&
161
162
163bool
165 return false;
166}
167
168
169bool
171 return false;
172}
173
174
175bool
178 // check if inspected parent is inspected
179 for (const auto& inspectedAC : myNet->getViewNet()->getInspectedElements().getACs()) {
180 if (inspectedAC->getTagProperty()->vehicleRouteEmbedded()) {
181 const auto demandElement = dynamic_cast<GNEDemandElement*>(inspectedAC);
182 if (demandElement && (demandElement->getChildDemandElements().size() > 0) &&
183 (demandElement->getChildDemandElements().at(0) == this)) {
184 return true;
185 }
186 }
187 }
188 }
189 // check opened popup
190 if (myNet->getViewNet()->getPopup()) {
191 return myNet->getViewNet()->getPopup()->getGLObject() == this;
192 }
193 return false;
194}
195
196
197bool
199 // get modes
200 const auto& modes = myNet->getViewNet()->getEditModes();
201 // get frames
202 const auto& personFramePlanSelector = myNet->getViewNet()->getViewParent()->getPersonFrame()->getPlanSelector();
203 const auto& personPlanFramePlanSelector = myNet->getViewNet()->getViewParent()->getPersonPlanFrame()->getPlanSelector();
204 const auto& containerFramePlanSelector = myNet->getViewNet()->getViewParent()->getContainerFrame()->getPlanSelector();
205 const auto& containerPlanFramePlanSelector = myNet->getViewNet()->getViewParent()->getContainerPlanFrame()->getPlanSelector();
206 // special case for Route
208 // get vehicle frame
209 const auto& vehicleFrame = myNet->getViewNet()->getViewParent()->getVehicleFrame();
210 // check if we're in vehicle mode
211 if (vehicleFrame->shown()) {
212 // get current vehicle template
213 const auto& vehicleTemplate = vehicleFrame->getVehicleTagSelector()->getCurrentTemplateAC();
214 // check if vehicle can be placed over route
215 if (vehicleTemplate && vehicleTemplate->getTagProperty()->vehicleRoute()) {
217 }
218 } else if (modes.isCurrentSupermodeDemand()) {
219 // check if we're in person or personPlan modes
220 if (((modes.demandEditMode == DemandEditMode::DEMAND_PERSON) && personFramePlanSelector->markRoutes()) ||
221 ((modes.demandEditMode == DemandEditMode::DEMAND_PERSONPLAN) && personPlanFramePlanSelector->markRoutes()) ||
222 ((modes.demandEditMode == DemandEditMode::DEMAND_CONTAINER) && containerFramePlanSelector->markRoutes()) ||
223 ((modes.demandEditMode == DemandEditMode::DEMAND_CONTAINERPLAN) && containerPlanFramePlanSelector->markRoutes())) {
225 }
226 }
227 }
228 return false;
229}
230
231
232bool
234 // get edit modes
235 const auto& editModes = myNet->getViewNet()->getEditModes();
236 // check if we're in delete mode
237 if (editModes.isCurrentSupermodeDemand() && (editModes.demandEditMode == DemandEditMode::DEMAND_DELETE)) {
239 } else {
240 return false;
241 }
242}
243
244
245bool
249 if (route && (route == myNet->getViewNet()->getViewObjectsSelector().getAttributeCarrierFront())) {
250 return (getParentDemandElements().at(1) == route);
251 }
254 if (vehicle && (vehicle == myNet->getViewNet()->getViewObjectsSelector().getAttributeCarrierFront())) {
255 return (getParentDemandElements().front() == vehicle);
256 }
257 }
258 return false;
259}
260
261
262bool
264 // get edit modes
265 const auto& editModes = myNet->getViewNet()->getEditModes();
266 // check if we're in select mode
267 if (editModes.isCurrentSupermodeDemand() && (editModes.demandEditMode == DemandEditMode::DEMAND_SELECT)) {
269 } else {
270 return false;
271 }
272}
273
274
275bool
277 // get edit modes
278 const auto& editModes = myNet->getViewNet()->getEditModes();
279 // check first set of conditions
280 if (!myNet->getViewNet()->isCurrentlyMovingElements() && // another elements are not currently moved
281 editModes.isCurrentSupermodeDemand() && // supermode demand
282 (editModes.demandEditMode == DemandEditMode::DEMAND_MOVE) && // move mode
283 myNet->getViewNet()->checkOverLockedElement(this, mySelected) && // no locked
284 myNet->getViewNet()->getViewObjectsSelector().getGUIGlObjectFront() == this) { // first element
285 // continue depending of subtype
286 if (myTagProperty->isVehicle()) {
287 // only vehicles over edges can be moved
289 return true;
290 } else {
291 return false;
292 }
293 } else if ((myTagProperty->isPerson() || myTagProperty->isContainer()) && (getChildDemandElements().size() > 0)) {
294 // only persons/containers with their first plan over edge can be moved
295 return getChildDemandElements().front()->getTagProperty()->planFromEdge();
296 } else {
297 return false;
298 }
299 } else {
300 return false;
301 }
302}
303
304
305void
307 throw InvalidArgument(getTagStr() + " doesn't have a demand element dialog");
308}
309
310
313 // create popup
314 GUIGLObjectPopupMenu* ret = new GUIGLObjectPopupMenu(app, parent, this);
315 // build common options
317 // show option to open demand element dialog
318 if (myTagProperty->hasDialog()) {
319 GUIDesigns::buildFXMenuCommand(ret, ("Open " + getTagStr() + " Dialog").c_str(), getACIcon(), &parent, MID_OPEN_ADDITIONAL_DIALOG);
320 new FXMenuSeparator(ret);
321 }
322 GUIDesigns::buildFXMenuCommand(ret, "Cursor position in view: " + toString(getPositionInView().x()) + "," + toString(getPositionInView().y()), nullptr, nullptr, 0);
323 return ret;
324}
325
326
329 // Create table
331 // Iterate over attributes
332 for (const auto& attrProperty : myTagProperty->getAttributeProperties()) {
333 // Add attribute and set it dynamic if aren't unique
334 if (attrProperty->isUnique()) {
335 ret->mkItem(attrProperty->getAttrStr().c_str(), false, getAttribute(attrProperty->getAttr()));
336 } else {
337 ret->mkItem(attrProperty->getAttrStr().c_str(), true, getAttribute(attrProperty->getAttr()));
338 }
339 }
340 // close building
341 ret->closeBuilding();
342 return ret;
343}
344
345
346bool
354
355
356void
360
361
362void
364 // we need an special checks due hierarchies
365 if (myTagProperty->isPlan()) {
366 // get person/container plarent
367 GNEDemandElement* planParent = getParentDemandElements().front();
368 // if this is the last person/container plan element, remove parent instead plan
369 if (planParent->getChildDemandElements().size() == 1) {
370 planParent->deleteGLObject();
371 } else {
373 }
375 // remove parent demand element
376 getParentDemandElements().front()->deleteGLObject();
377 } else {
379 }
380}
381
382
383void
393
394
395void
399
400
401bool
405
406// ---------------------------------------------------------------------------
407// GNEDemandElement - protected methods
408// ---------------------------------------------------------------------------
409
410bool
411GNEDemandElement::isValidDemandElementID(const std::string& value) const {
412 if (!isTemplate() && (value == getID())) {
413 return true;
414 } else if (SUMOXMLDefinitions::isValidVehicleID(value)) {
415 return (myNet->getAttributeCarriers()->retrieveDemandElement(myTagProperty->getTag(), value, false) == nullptr);
416 } else {
417 return false;
418 }
419}
420
421
422bool
423GNEDemandElement::isValidDemandElementID(const std::vector<SumoXMLTag>& tags, const std::string& value) const {
424 if (isTemplate() && value.empty()) {
425 return true;
426 } else if (!isTemplate() && (value == getID())) {
427 return true;
428 } else if (SUMOXMLDefinitions::isValidVehicleID(value)) {
429 return (myNet->getAttributeCarriers()->retrieveDemandElements(tags, value, false) == nullptr);
430 } else {
431 return false;
432 }
433}
434
435
436void
437GNEDemandElement::setDemandElementID(const std::string& newID) {
438 // update ID
440 setMicrosimID(newID);
441 } else {
443 }
444 // check if update ids of child elements
446 // Change IDs of all person plans children (stops, embedded routes...)
447 for (const auto& childDemandElement : getChildDemandElements()) {
448 childDemandElement->setDemandElementID(getID());
449 }
450 }
451}
452
453
456 if (getParentDemandElements().size() < 1) {
457 throw InvalidArgument("This demand element doesn't have a type parent");
458 } else if (!getParentDemandElements().at(0)->getTagProperty()->isType()
459 && !getParentDemandElements().at(0)->getTagProperty()->isTypeDist()) {
460 throw InvalidArgument("The first parent isn't a type");
461 } else {
462 return getParentDemandElements().at(0);
463 }
464}
465
466
469 if (getParentDemandElements().size() < 2) {
470 throw InvalidArgument("This demand element doesn't have two parent");
471 } else if (getParentDemandElements().at(1)->getTagProperty()->getTag() != SUMO_TAG_ROUTE) {
472 throw InvalidArgument("This demand element doesn't have a route parent");
473 } else {
474 return getParentDemandElements().at(1);
475 }
476}
477
478
479std::vector<GNEDemandElement*>
482 // get stops
483 std::vector<GNEDemandElement*> invalidStops;
484 // get edge stop index
485 const auto edgeStopIndex = getEdgeStopIndex();
486 // take all stops/waypoints with index = -1
487 for (const auto& edgeStop : edgeStopIndex) {
488 if (edgeStop.stopIndex == -1) {
489 for (const auto& stop : edgeStop.stops) {
490 invalidStops.push_back(stop);
491 }
492 }
493 }
494 return invalidStops;
495 } else {
496 return {};
497 }
498}
499
500
501void
503 // get two points
504 const Position posA = element->getParentJunctions().front()->getPositionInView();
505 const Position posB = element->getParentJunctions().back()->getPositionInView();
506 const double rot = ((double)atan2((posB.x() - posA.x()), (posA.y() - posB.y())) * (double) 180.0 / (double)M_PI);
507 const double len = posA.distanceTo2D(posB);
508 // push draw matrix
510 // Start with the drawing of the area traslating matrix to origin
511 drawInLayer(element->getType() + 0.1);
512 // set trip color
514 // draw line
515 GLHelper::drawBoxLine(posA, rot, len, 0.25);
516 // pop draw matrix
518}
519
520
521void
522GNEDemandElement::drawStackLabel(const int number, const std::string& element, const Position& position, const double rotation,
523 const double width, const double length, const double exaggeration) const {
524 // declare contour width
525 const double contourWidth = (0.05 * exaggeration);
526 // Push matrix
528 // Traslate to top
529 glTranslated(position.x(), position.y(), GLO_VEHICLELABELS);
530 glRotated(rotation, 0, 0, -1);
531 glTranslated((width * exaggeration * 0.5) + (0.35 * exaggeration) + 0.05, 0, 0);
532 // draw external box
534 GLHelper::drawBoxLine(Position(), 0, (length * exaggeration), 0.3 * exaggeration);
535 // draw internal box
536 glTranslated(0, 0, 0.1);
537 GLHelper::setColor(RGBColor(0, 128, 0));
538 GLHelper::drawBoxLine(Position(0, -contourWidth), Position(0, -contourWidth), 0, (length * exaggeration) - (contourWidth * 2), (0.3 * exaggeration) - contourWidth);
539 // draw stack label
540 GLHelper::drawText(element + "s stacked: " + toString(number), Position(0, length * exaggeration * -0.5), (.1 * exaggeration), (0.6 * exaggeration), RGBColor::WHITE, 90, 0, -1);
541 // pop draw matrix
543}
544
545
546void
547GNEDemandElement::replaceParentEdges(const std::string& value) {
548 auto newEdges = parse<GNEHierarchicalContainerParents<GNEEdge*> >(getNet(), value);
550}
551
552
553void
555 auto newLane = myNet->getAttributeCarriers()->retrieveLane(value);
556 GNEHierarchicalElement::updateParent(this, 0, newLane);
557}
558
559
560void
562 auto newJunction = myNet->getAttributeCarriers()->retrieveJunction(value);
563 GNEHierarchicalElement::updateParent(this, 0, newJunction);
564}
565
566
567void
569 auto newJunction = myNet->getAttributeCarriers()->retrieveJunction(value);
570 GNEHierarchicalElement::updateParent(this, (int)getParentJunctions().size() - 1, newJunction);
571}
572
573
574void
576 auto newEdge = myNet->getAttributeCarriers()->retrieveEdge(value);
577 GNEHierarchicalElement::updateParent(this, 0, newEdge);
578}
579
580
581void
583 auto newEdge = myNet->getAttributeCarriers()->retrieveEdge(value);
584 GNEHierarchicalElement::updateParent(this, (int)getParentEdges().size() - 1, newEdge);
585}
586
587
588void
590 auto newAdditional = myNet->getAttributeCarriers()->retrieveAdditional(tag, value);
591 GNEHierarchicalElement::updateParent(this, 0, newAdditional);
592}
593
594
595void
597 auto newAdditional = myNet->getAttributeCarriers()->retrieveAdditional(tag, value);
598 GNEHierarchicalElement::updateParent(this, (int)getParentAdditionals().size() - 1, newAdditional);
599}
600
601
602void
603GNEDemandElement::replaceDemandElementParent(SumoXMLTag tag, const std::string& value, const int parentIndex) {
604 auto newDemandElement = myNet->getAttributeCarriers()->retrieveDemandElement(tag, value);
605 GNEHierarchicalElement::updateParent(this, parentIndex, newDemandElement);
606}
607
608
609bool
611 // throw exception because this function mus be implemented in child (see GNEE3Detector)
612 throw ProcessError(StringUtils::format("Calling non-implemented function checkChildDemandElementRestriction during saving of %. It muss be reimplemented in child class", getTagStr()));
613}
614
615
616std::vector<GNEDemandElement::EdgeStopIndex>
618 std::vector<GNEDemandElement::EdgeStopIndex> edgeStopIndex;
619 // first check that this stop has parent
620 if (getParentDemandElements().size() > 0) {
621 // get path edges depending of parent
622 std::vector<GNEEdge*> pathEdges;
623 // get parent demand element
624 const auto parent = getParentDemandElements().front();
625 // continue depending of parent
626 if (parent->getTagProperty()->hasAttribute(SUMO_ATTR_EDGES)) {
627 pathEdges = parent->getParentEdges();
628 } else if (parent->getTagProperty()->vehicleRoute()) {
629 // get route edges
630 if (parent->getParentDemandElements().size() > 1) {
631 pathEdges = parent->getParentDemandElements().at(1)->getParentEdges();
632 }
633 } else if (parent->getTagProperty()->vehicleRouteEmbedded()) {
634 // get embedded route edges
635 pathEdges = parent->getChildDemandElements().front()->getParentEdges();
636 } else {
637 // get last parent edge
638 const auto lastEdge = parent->getParentEdges().back();
639 bool stop = false;
640 const auto& pathElementSegments = myNet->getDemandPathManager()->getPathElementSegments(parent);
641 // extract all edges from pathElement parent
642 for (auto it = pathElementSegments.begin(); (it != pathElementSegments.end()) && !stop; it++) {
643 if ((*it)->getLane()) {
644 pathEdges.push_back((*it)->getLane()->getParentEdge());
645 // stop if path correspond to last edge
646 if (pathEdges.back() == lastEdge) {
647 stop = true;
648 }
649 }
650 }
651 }
652 // get all parent's stops and waypoints sorted by position
653 for (const auto& demandElement : parent->getChildDemandElements()) {
654 if (demandElement->getTagProperty()->isVehicleStop()) {
655 // get stop/waypoint edge
656 GNEEdge* edge = nullptr;
657 if (demandElement->getParentAdditionals().size() > 0) {
658 edge = demandElement->getParentAdditionals().front()->getParentLanes().front()->getParentEdge();
659 } else {
660 edge = demandElement->getParentLanes().front()->getParentEdge();
661 }
662 // check if add a new edgeStopIndex or update last
663 if ((edgeStopIndex.size() > 0) && (edgeStopIndex.back().edge == edge)) {
664 edgeStopIndex.back().stops.push_back(demandElement);
665 } else {
666 edgeStopIndex.push_back(EdgeStopIndex(edge, demandElement));
667 }
668 }
669 }
670 // declare index for current stop
671 int currentEdgeStopIndex = 0;
672 for (int i = 0; (i < (int)pathEdges.size()) && (currentEdgeStopIndex < (int)edgeStopIndex.size()); i++) {
673 // check if current edge stop index is in the path
674 if (edgeStopIndex[currentEdgeStopIndex].edge == pathEdges.at(i)) {
675 edgeStopIndex[currentEdgeStopIndex].stopIndex = i;
676 currentEdgeStopIndex++;
677 } else {
678 // check if edge exist in the rest of the path
679 bool next = false;
680 for (int j = (i + 1); j < (int)pathEdges.size(); j++) {
681 if (edgeStopIndex[currentEdgeStopIndex].edge == pathEdges.at(j)) {
682 next = true;
683 }
684 }
685 if (!next) {
686 // ignore current stops (because is out of path)
687 currentEdgeStopIndex++;
688 }
689 }
690 }
691 }
692 // sort stops by position
693 for (auto& edgeStop : edgeStopIndex) {
694 if (edgeStop.stops.size() > 1) {
695 // copy all stops to a map to sort it by endPos
696 std::map<double, std::vector<GNEDemandElement*> > sortedStops;
697 for (const auto& stop : edgeStop.stops) {
698 if (sortedStops.count(stop->getAttributeDouble(SUMO_ATTR_ENDPOS)) == 0) {
699 sortedStops[stop->getAttributeDouble(SUMO_ATTR_ENDPOS)] = {stop};
700 } else {
701 sortedStops[stop->getAttributeDouble(SUMO_ATTR_ENDPOS)].push_back(stop);
702 }
703 }
704 // update stops with sorted stops
705 edgeStop.stops.clear();
706 for (const auto& sortedStop : sortedStops) {
707 edgeStop.stops.insert(edgeStop.stops.end(), sortedStop.second.begin(), sortedStop.second.end());
708 }
709 }
710 }
711 return edgeStopIndex;
712}
713
714
717 // set color depending of color active
718 switch (c.getActive()) {
719 case 0: {
720 // test for emergency vehicle
721 if (getTypeParent()->getAttribute(SUMO_ATTR_GUISHAPE) == "emergency") {
722 return RGBColor::WHITE;
723 }
724 // test for firebrigade
725 if (getTypeParent()->getAttribute(SUMO_ATTR_GUISHAPE) == "firebrigade") {
726 return RGBColor::RED;
727 }
728 // test for police car
729 if (getTypeParent()->getAttribute(SUMO_ATTR_GUISHAPE) == "police") {
730 return RGBColor::BLUE;
731 }
732 if (getTypeParent()->getAttribute(SUMO_ATTR_GUISHAPE) == "scooter") {
733 return RGBColor::WHITE;
734 }
735 // check if color was set
736 if (parameters->wasSet(VEHPARS_COLOR_SET)) {
737 return parameters->color;
738 } else {
739 // take their parent's color)
740 return getTypeParent()->getColor();
741 }
742 }
743 case 2: {
744 if (parameters->wasSet(VEHPARS_COLOR_SET)) {
745 return parameters->color;
746 } else {
747 return c.getScheme().getColor(0);
748 }
749 }
750 case 3: {
752 return getTypeParent()->getColor();
753 } else {
754 return c.getScheme().getColor(0);
755 }
756 break;
757 }
758 case 4: {
760 return getRouteParent()->getColor();
761 } else {
762 return c.getScheme().getColor(0);
763 }
764 }
765 case 5: {
766 Position p = getRouteParent()->getParentEdges().at(0)->getChildLanes().at(0)->getLaneShape()[0];
767 const Boundary& b = myNet->getBoundary();
768 Position center = b.getCenter();
769 double hue = 180. + atan2(center.x() - p.x(), center.y() - p.y()) * 180. / M_PI;
770 double sat = p.distanceTo(center) / center.distanceTo(Position(b.xmin(), b.ymin()));
771 return RGBColor::fromHSV(hue, sat, 1.);
772 }
773 case 6: {
774 Position p = getRouteParent()->getParentEdges().back()->getChildLanes().at(0)->getLaneShape()[-1];
775 const Boundary& b = myNet->getBoundary();
776 Position center = b.getCenter();
777 double hue = 180. + atan2(center.x() - p.x(), center.y() - p.y()) * 180. / M_PI;
778 double sat = p.distanceTo(center) / center.distanceTo(Position(b.xmin(), b.ymin()));
779 return RGBColor::fromHSV(hue, sat, 1.);
780 }
781 case 7: {
782 Position pb = getRouteParent()->getParentEdges().at(0)->getChildLanes().at(0)->getLaneShape()[0];
783 Position pe = getRouteParent()->getParentEdges().back()->getChildLanes().at(0)->getLaneShape()[-1];
784 const Boundary& b = myNet->getBoundary();
785 double hue = 180. + atan2(pb.x() - pe.x(), pb.y() - pe.y()) * 180. / M_PI;
786 Position minp(b.xmin(), b.ymin());
787 Position maxp(b.xmax(), b.ymax());
788 double sat = pb.distanceTo(pe) / minp.distanceTo(maxp);
789 return RGBColor::fromHSV(hue, sat, 1.);
790 }
791 case 35: { // color randomly (by pointer hash)
792 std::hash<const GNEDemandElement*> ptr_hash;
793 const double hue = (double)(ptr_hash(this) % 360); // [0-360]
794 const double sat = (double)((ptr_hash(this) / 360) % 67) / 100. + 0.33; // [0.33-1]
795 return RGBColor::fromHSV(hue, sat, 1.);
796 }
797 default: {
798 return c.getScheme().getColor(0);
799 }
800 }
801}
802
803
804void
806 std::vector<GNEEdge*> edges;
807 if (myTagProperty->isRoute()) {
808 edges = getParentEdges();
809 } else if (myTagProperty->vehicleRoute()) {
810 edges = getParentDemandElements().at(1)->getParentEdges();
811 } else if (myTagProperty->vehicleRouteEmbedded()) {
812 edges = getChildDemandElements().front()->getParentEdges();
813 } else if (myTagProperty->vehicleEdges()) {
814 edges = getParentEdges();
815 }
816 // calculate path
818 // check path size
819 if (path.size() > 0) {
820 double length = 0;
821 for (const auto& edge : path) {
822 length += edge->getNBEdge()->getFinalLength();
823 }
824 for (int i = 0; i < ((int)path.size() - 1); i++) {
825 length += path.at(i)->getChildLanes().front()->getLane2laneConnections().getLane2laneGeometry(path.at(i + 1)->getChildLanes().front()).getShape().length();
826 }
827 GUIDesigns::buildFXMenuCommand(ret, TL("Route length: ") + toString(length), nullptr, ret, MID_COPY_NAME);
828 }
829}
830
831
832void
834 // create menu pane for transform operations
835 FXMenuPane* transformOperation = new FXMenuPane(ret);
836 ret->insertMenuPaneChild(transformOperation);
837 auto reverseMenuCascade = new FXMenuCascade(ret, TL("reverse"), nullptr, transformOperation);
838 // build menu commands
839 GUIDesigns::buildFXMenuCommand(transformOperation, TLF("reverse current %", myTagProperty->getTagStr()), nullptr, myNet->getViewNet(), MID_GNE_REVERSE);
840 GUIDesigns::buildFXMenuCommand(transformOperation, TLF("Add reverse %", myTagProperty->getTagStr()), nullptr, myNet->getViewNet(), MID_GNE_ADDREVERSE);
841 // check if reverse can be added
842 if (GNERouteHandler::canReverse(this)) {
843 reverseMenuCascade->enable();
844 } else {
845 reverseMenuCascade->disable();
846 }
847}
848
849/****************************************************************************/
@ 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:469
@ MID_COPY_NAME
Copy object name - popup entry.
Definition GUIAppEnum.h:453
@ GLO_VEHICLELABELS
stack and flow labels (used in netedit)
#define TL(string)
Definition MsgHandler.h:301
#define TLF(string,...)
Definition MsgHandler.h:303
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
@ 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:748
const std::string getID() const
get ID (all Attribute Carriers have one)
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)
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
const GNETagProperties * getTagProperty() const
get tagProperty associated with this Attribute Carrier
GNENet * myNet
pointer to net
GNENet * getNet() const
get pointer to net
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
virtual void updateGeometry()=0
update pre-computed geometry information
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 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
bool checkDrawOverContour() const
check if draw over contour (orange)
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
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 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
virtual const RGBColor & getColor() const =0
get color
GUIGlObject * getGUIGlObject()
get GUIGlObject associated with this AttributeCarrier
bool isPathElementSelected() const
check if path element is selected
bool checkDrawToContour() const
check if draw from contour (magenta)
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 selectGLObject()
select element
bool checkDrawMoveContour() const
check if draw move contour (red)
bool checkDrawDeleteContour() const
check if draw delete contour (pink/white)
void setDemandElementID(const std::string &newID)
set demand element id
bool checkDrawDeleteContourSmall() const
check if draw delete contour small (pink/white)
GUIGeometry mySpreadGeometry
demand element spread geometry (Only used by vehicles and pedestrians)
void buildMenuAddReverse(GUIGLObjectPopupMenu *ret) const
build menu command route length
void replaceFirstParentJunction(const std::string &value)
replace the first parent junction
std::vector< EdgeStopIndex > getEdgeStopIndex() const
get edgeStopIndex
bool checkDrawRelatedContour() const
check if draw related contour (cyan)
void updateGLObject()
update GLObject (geometry, ID, etc.)
GNEDemandElement * getTypeParent() const
get type parent (needed because first parent can be either type or typeDistribution)
bool checkDrawSelectContour() const
check if draw select contour (blue)
void replaceParentEdges(const std::string &value)
all edges
GNEHierarchicalElement * getHierarchicalElement()
get GNEHierarchicalElement associated with this AttributeCarrier
void replaceFirstParentEdge(const std::string &value)
replace the first parent edge
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.
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 GUIGLObjectPopupMenu * getPopUpMenu(GUIMainWindow &app, GUISUMOAbstractView &parent)
Returns an own popup-menu.
virtual bool checkChildDemandElementRestriction() const
check restriction with the number of children
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
void replaceFirstParentLane(const std::string &value)
replace the first parent lane
bool isGLObjectLocked() const
check if element is locked
void markAsFrontElement()
mark element as front element
void replaceLastParentAdditional(SumoXMLTag tag, const std::string &value)
replace the last parent additional
virtual ~GNEDemandElement()
Destructor.
virtual void openDemandElementDialog()
open DemandElement Dialog
void deleteGLObject()
delete element
void replaceLastParentJunction(const std::string &value)
replace the last parent junction
bool checkDrawFromContour() const
check if draw from contour (green)
A road/street connecting two junctions (netedit-version)
Definition GNEEdge.h:53
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
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:220
double myMoveElementLateralOffset
move element lateral offset (used by elements placed over lanes
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:748
const Boundary & getBoundary() const
returns the bounder of the network
Definition GNENet.cpp:188
GNEPathManager * getDemandPathManager()
get demand path manager
Definition GNENet.cpp:176
GNENetHelper::AttributeCarriers * getAttributeCarriers() const
get all attribute carriers used in this net
Definition GNENet.cpp:146
GNEViewNet * getViewNet() const
get view net
Definition GNENet.cpp:2194
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
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