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-2024 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>
23#include <netedit/GNEViewNet.h>
36
37#include "GNEDemandElement.h"
38#include "GNERouteHandler.h"
39
40// ===========================================================================
41// member method definitions
42// ===========================================================================
43
44GNEDemandElement::GNEDemandElement(const std::string& id, GNENet* net, GUIGlObjectType type, SumoXMLTag tag, FXIcon* icon, const int options,
45 const std::vector<GNEJunction*>& junctionParents,
46 const std::vector<GNEEdge*>& edgeParents,
47 const std::vector<GNELane*>& laneParents,
48 const std::vector<GNEAdditional*>& additionalParents,
49 const std::vector<GNEDemandElement*>& demandElementParents,
50 const std::vector<GNEGenericData*>& genericDataParents) :
51 GNEPathElement(type, id, icon, options),
52 GNEHierarchicalElement(net, tag, junctionParents, edgeParents, laneParents, additionalParents, demandElementParents, genericDataParents),
54 myStackedLabelNumber(0) {
55 // check if is template
56 myIsTemplate = id.empty();
57}
58
59
60GNEDemandElement::GNEDemandElement(GNEDemandElement* demandElementParent, GNENet* net, GUIGlObjectType type, SumoXMLTag tag, FXIcon* icon, const int options,
61 const std::vector<GNEJunction*>& junctionParents,
62 const std::vector<GNEEdge*>& edgeParents,
63 const std::vector<GNELane*>& laneParents,
64 const std::vector<GNEAdditional*>& additionalParents,
65 const std::vector<GNEDemandElement*>& demandElementParents,
66 const std::vector<GNEGenericData*>& genericDataParents) :
67 GNEPathElement(type, demandElementParent->getID(), icon, options),
68 GNEHierarchicalElement(net, tag, junctionParents, edgeParents, laneParents, additionalParents, demandElementParents, genericDataParents),
70 myStackedLabelNumber(0) {
71}
72
73
75
76
77void
78GNEDemandElement::removeGeometryPoint(const Position /*clickedPosition*/, GNEUndoList* /*undoList*/) {
79 // currently there isn't demand elements with removable geometry points
80}
81
82
85 return this;
86}
87
88
89const GUIGlObject*
91 return this;
92}
93
94
95const GUIGeometry&
99
100
103 // first check if there are demand elements
104 if (getChildDemandElements().empty()) {
105 return nullptr;
106 } else {
107 // find child demand element
108 auto it = std::find(getChildDemandElements().begin(), getChildDemandElements().end(), demandElement);
109 // return element or null depending of iterator
110 if (it == getChildDemandElements().end()) {
111 // in this case, we assume that the last child is the previos child
112 return getChildDemandElements().back();
113 } else if (it == getChildDemandElements().begin()) {
114 return nullptr;
115 } else {
116 return *(it - 1);
117 }
118 }
119}
120
121
124 // find child demand element
125 auto it = std::find(getChildDemandElements().begin(), getChildDemandElements().end(), demandElement);
126 // return element or null depending of iterator
127 if (it == getChildDemandElements().end()) {
128 return nullptr;
129 } else if (it == (getChildDemandElements().end() - 1)) {
130 return nullptr;
131 } else {
132 return *(it + 1);
133 }
134}
135
136
137void
141
142
143void
147
148
149void
153
154
155const GUIGeometry&
159
160
161bool
163 return false;
164}
165
166
167bool
169 return false;
170}
171
172
173bool
176 // check if inspected parent is inspected
177 for (const auto &inspectedAC : myNet->getViewNet()->getInspectedElements().getACs()) {
178 if (inspectedAC->getTagProperty().vehicleRouteEmbedded()) {
179 const auto demandElement = dynamic_cast<GNEDemandElement*>(inspectedAC);
180 if (demandElement && (demandElement->getChildDemandElements().size() > 0) &&
181 (demandElement->getChildDemandElements().at(0) == this)) {
182 return true;
183 }
184 }
185 }
186 return false;
187 } else {
188 return false;
189 }
190}
191
192
193bool
195 // get modes
196 const auto& modes = myNet->getViewNet()->getEditModes();
197 // get frames
198 const auto& personFramePlanSelector = myNet->getViewNet()->getViewParent()->getPersonFrame()->getPlanSelector();
199 const auto& personPlanFramePlanSelector = myNet->getViewNet()->getViewParent()->getPersonPlanFrame()->getPlanSelector();
200 const auto& containerFramePlanSelector = myNet->getViewNet()->getViewParent()->getContainerFrame()->getPlanSelector();
201 const auto& containerPlanFramePlanSelector = myNet->getViewNet()->getViewParent()->getContainerPlanFrame()->getPlanSelector();
202 // special case for Route
204 // get vehicle frame
205 const auto& vehicleFrame = myNet->getViewNet()->getViewParent()->getVehicleFrame();
206 // check if we're in vehicle mode
207 if (vehicleFrame->shown()) {
208 // get current vehicle template
209 const auto& vehicleTemplate = vehicleFrame->getVehicleTagSelector()->getCurrentTemplateAC();
210 // check if vehicle can be placed over route
211 if (vehicleTemplate && vehicleTemplate->getTagProperty().vehicleRoute()) {
213 }
214 } else if (modes.isCurrentSupermodeDemand()) {
215 // check if we're in person or personPlan modes
216 if (((modes.demandEditMode == DemandEditMode::DEMAND_PERSON) && personFramePlanSelector->markRoutes()) ||
217 ((modes.demandEditMode == DemandEditMode::DEMAND_PERSONPLAN) && personPlanFramePlanSelector->markRoutes()) ||
218 ((modes.demandEditMode == DemandEditMode::DEMAND_CONTAINER) && containerFramePlanSelector->markRoutes()) ||
219 ((modes.demandEditMode == DemandEditMode::DEMAND_CONTAINERPLAN) && containerPlanFramePlanSelector->markRoutes())) {
221 }
222 }
223 }
224 return false;
225}
226
227
228bool
230 // get edit modes
231 const auto& editModes = myNet->getViewNet()->getEditModes();
232 // check if we're in delete mode
233 if (editModes.isCurrentSupermodeDemand() && (editModes.demandEditMode == DemandEditMode::DEMAND_DELETE)) {
235 } else {
236 return false;
237 }
238}
239
240
241bool
243 // get edit modes
244 const auto& editModes = myNet->getViewNet()->getEditModes();
245 // check if we're in select mode
246 if (editModes.isCurrentSupermodeDemand() && (editModes.demandEditMode == DemandEditMode::DEMAND_SELECT)) {
248 } else {
249 return false;
250 }
251}
252
253
254bool
256 // get edit modes
257 const auto& editModes = myNet->getViewNet()->getEditModes();
258 // check first set of conditions
259 if (!myNet->getViewNet()->isCurrentlyMovingElements() && // another elements are not currently moved
260 editModes.isCurrentSupermodeDemand() && // supermode demand
261 (editModes.demandEditMode == DemandEditMode::DEMAND_MOVE) && // move mode
262 myNet->getViewNet()->checkOverLockedElement(this, mySelected) && // no locked
263 myNet->getViewNet()->getViewObjectsSelector().getGUIGlObjectFront() == this) { // first element
264 // continue depending of subtype
265 if (myTagProperty.isVehicle()) {
266 // only vehicles over edges can be moved
268 return true;
269 } else {
270 return false;
271 }
272 } else if ((myTagProperty.isPerson() || myTagProperty.isContainer()) && (getChildDemandElements().size() > 0)) {
273 // only persons/containers with their first plan over edge can be moved
274 return getChildDemandElements().front()->getTagProperty().planFromEdge();
275 } else {
276 return false;
277 }
278 } else {
279 return false;
280 }
281}
282
283
284void
286 throw InvalidArgument(getTagStr() + " doesn't have a demand element dialog");
287}
288
289
292 GUIGLObjectPopupMenu* ret = new GUIGLObjectPopupMenu(app, parent, *this);
293 // build header
294 buildPopupHeader(ret, app);
295 // build menu command for center button and copy cursor position to clipboard
297 buildPositionCopyEntry(ret, app);
298 // build menu commands for names
299 GUIDesigns::buildFXMenuCommand(ret, "Copy " + getTagStr() + " name to clipboard", nullptr, ret, MID_COPY_NAME);
300 GUIDesigns::buildFXMenuCommand(ret, "Copy " + getTagStr() + " typed name to clipboard", nullptr, ret, MID_COPY_TYPED_NAME);
301 new FXMenuSeparator(ret);
302 // build selection and show parameters menu
305 // show option to open demand element dialog
306 if (myTagProperty.hasDialog()) {
307 GUIDesigns::buildFXMenuCommand(ret, ("Open " + getTagStr() + " Dialog").c_str(), getACIcon(), &parent, MID_OPEN_ADDITIONAL_DIALOG);
308 new FXMenuSeparator(ret);
309 }
310 GUIDesigns::buildFXMenuCommand(ret, "Cursor position in view: " + toString(getPositionInView().x()) + "," + toString(getPositionInView().y()), nullptr, nullptr, 0);
311 return ret;
312}
313
314
317 // Create table
319 // Iterate over attributes
320 for (const auto& i : myTagProperty) {
321 // Add attribute and set it dynamic if aren't unique
322 if (i.isUnique()) {
323 ret->mkItem(i.getAttrStr().c_str(), false, getAttribute(i.getAttr()));
324 } else {
325 ret->mkItem(i.getAttrStr().c_str(), true, getAttribute(i.getAttr()));
326 }
327 }
328 // close building
329 ret->closeBuilding();
330 return ret;
331}
332
333
334bool
342
343
344void
348
349
350void
352 // we need an special checks due hierarchies
353 if (myTagProperty.isPlan()) {
354 // get person/container plarent
355 GNEDemandElement* planParent = getParentDemandElements().front();
356 // if this is the last person/container plan element, remove parent instead plan
357 if (planParent->getChildDemandElements().size() == 1) {
358 planParent->deleteGLObject();
359 } else {
361 }
363 // remove parent demand element
364 getParentDemandElements().front()->deleteGLObject();
365 } else {
367 }
368}
369
370
371void
381
382
383void
387
388
389bool
393
394// ---------------------------------------------------------------------------
395// GNEDemandElement - protected methods
396// ---------------------------------------------------------------------------
397
398bool
399GNEDemandElement::isValidDemandElementID(const std::string& value) const {
400 if (!isTemplate() && (value == getID())) {
401 return true;
402 } else if (SUMOXMLDefinitions::isValidVehicleID(value)) {
403 return (myNet->getAttributeCarriers()->retrieveDemandElement(myTagProperty.getTag(), value, false) == nullptr);
404 } else {
405 return false;
406 }
407}
408
409
410bool
411GNEDemandElement::isValidDemandElementID(const std::vector<SumoXMLTag>& tags, const std::string& value) const {
412 if (value == getID()) {
413 return true;
414 } else if (SUMOXMLDefinitions::isValidVehicleID(value)) {
415 return (myNet->getAttributeCarriers()->retrieveDemandElements(tags, value, false) == nullptr);
416 } else {
417 return false;
418 }
419}
420
421
422void
423GNEDemandElement::setDemandElementID(const std::string& newID) {
424 // update ID
426 setMicrosimID(newID);
427 } else {
429 }
430 // check if update ids of child elements
432 // Change IDs of all person plans children (stops, embedded routes...)
433 for (const auto& childDemandElement : getChildDemandElements()) {
434 childDemandElement->setDemandElementID(getID());
435 }
436 }
437}
438
439
442 if (getParentDemandElements().size() < 1) {
443 throw InvalidArgument("This demand element doesn't have a type parent");
444 } else if (!getParentDemandElements().at(0)->getTagProperty().isType()
445 && !getParentDemandElements().at(0)->getTagProperty().isTypeDist()) {
446 throw InvalidArgument("The first parent isn't a type");
447 } else if (getParentDemandElements().at(0)->getTagProperty().getTag() == SUMO_TAG_VTYPE) {
448 return getParentDemandElements().at(0);
449 } else {
450 // get typeDistribution ID
451 const auto typeDistributionID = getParentDemandElements().at(0)->getID();
452 // obtain all types with the given typeDistribution sorted by ID
453 std::map<std::string, GNEDemandElement*> sortedTypes;
454 for (const auto& type : myNet->getAttributeCarriers()->getDemandElements().at(SUMO_TAG_VTYPE)) {
455 if (type.second->getAttribute(GNE_ATTR_VTYPE_DISTRIBUTION) == typeDistributionID) {
456 sortedTypes[type.second->getID()] = type.second;
457 }
458 }
459 // return first type, or default vType
460 if (sortedTypes.size() > 0) {
461 return sortedTypes.begin()->second;
462 } else if (myNet->getAttributeCarriers()->getDemandElements().size() > 0) {
463 return myNet->getAttributeCarriers()->getDemandElements().at(SUMO_TAG_VTYPE).begin()->second;
464 } else {
465 throw InvalidArgument("no vTypes");
466 }
467 }
468}
469
470
473 if (getParentDemandElements().size() < 2) {
474 throw InvalidArgument("This demand element doesn't have two parent");
475 } else if (getParentDemandElements().at(1)->getTagProperty().getTag() != SUMO_TAG_ROUTE) {
476 throw InvalidArgument("This demand element doesn't have a route parent");
477 } else {
478 return getParentDemandElements().at(1);
479 }
480}
481
482
483std::vector<GNEDemandElement*>
486 // get stops
487 std::vector<GNEDemandElement*> invalidStops;
488 // get edge stop index
489 const auto edgeStopIndex = getEdgeStopIndex();
490 // take all stops/waypoints with index = -1
491 for (const auto& edgeStop : edgeStopIndex) {
492 if (edgeStop.stopIndex == -1) {
493 for (const auto& stop : edgeStop.stops) {
494 invalidStops.push_back(stop);
495 }
496 }
497 }
498 return invalidStops;
499 } else {
500 return {};
501 }
502}
503
504
505void
507 // get two points
508 const Position posA = element->getParentJunctions().front()->getPositionInView();
509 const Position posB = element->getParentJunctions().back()->getPositionInView();
510 const double rot = ((double)atan2((posB.x() - posA.x()), (posA.y() - posB.y())) * (double) 180.0 / (double)M_PI);
511 const double len = posA.distanceTo2D(posB);
512 // push draw matrix
514 // Start with the drawing of the area traslating matrix to origin
515 drawInLayer(element->getType() + 0.1);
516 // set trip color
518 // draw line
519 GLHelper::drawBoxLine(posA, rot, len, 0.25);
520 // pop draw matrix
522}
523
524
525void
526GNEDemandElement::drawStackLabel(const int number, const std::string& element, const Position& position, const double rotation,
527 const double width, const double length, const double exaggeration) const {
528 // declare contour width
529 const double contourWidth = (0.05 * exaggeration);
530 // Push matrix
532 // Traslate to top
533 glTranslated(position.x(), position.y(), GLO_VEHICLELABELS);
534 glRotated(rotation, 0, 0, -1);
535 glTranslated((width * exaggeration * 0.5) + (0.35 * exaggeration) + 0.05, 0, 0);
536 // draw external box
538 GLHelper::drawBoxLine(Position(), 0, (length * exaggeration), 0.3 * exaggeration);
539 // draw internal box
540 glTranslated(0, 0, 0.1);
541 GLHelper::setColor(RGBColor(0, 128, 0));
542 GLHelper::drawBoxLine(Position(0, -contourWidth), Position(0, -contourWidth), 0, (length * exaggeration) - (contourWidth * 2), (0.3 * exaggeration) - contourWidth);
543 // draw stack label
544 GLHelper::drawText(element + "s stacked: " + toString(number), Position(0, length * exaggeration * -0.5), (.1 * exaggeration), (0.6 * exaggeration), RGBColor::WHITE, 90, 0, -1);
545 // pop draw matrix
547}
548
549
550void
552 replaceParentElements(this, parse<std::vector<GNEEdge*> >(getNet(), value));
553}
554
555
556void
558 replaceParentElements(this, parse<std::vector<GNELane*> >(getNet(), value));
559}
560
561
562void
564 std::vector<GNEJunction*> parentJunctions = getParentJunctions();
565 parentJunctions[0] = myNet->getAttributeCarriers()->retrieveJunction(value);
566 // replace parent junctions
567 replaceParentElements(this, parentJunctions);
568}
569
570
571void
573 std::vector<GNEJunction*> parentJunctions = getParentJunctions();
574 parentJunctions[(int)parentJunctions.size() - 1] = myNet->getAttributeCarriers()->retrieveJunction(value);
575 // replace parent junctions
576 replaceParentElements(this, parentJunctions);
577}
578
579
580void
582 std::vector<GNEEdge*> parentEdges = getParentEdges();
583 parentEdges[0] = myNet->getAttributeCarriers()->retrieveEdge(value);
584 // replace parent edges
585 replaceParentElements(this, parentEdges);
586}
587
588
589void
591 std::vector<GNEEdge*> parentEdges = getParentEdges();
592 parentEdges[(int)parentEdges.size() - 1] = myNet->getAttributeCarriers()->retrieveEdge(value);
593 // replace parent edges
594 replaceParentElements(this, parentEdges);
595}
596
597
598void
600 std::vector<GNEAdditional*> parentAdditionals = getParentAdditionals();
601 parentAdditionals[0] = myNet->getAttributeCarriers()->retrieveAdditional(tag, value);
602 // replace parent additionals
603 replaceParentElements(this, parentAdditionals);
604}
605
606
607void
609 std::vector<GNEAdditional*> parentAdditionals = getParentAdditionals();
610 parentAdditionals[(int)parentAdditionals.size() - 1] = myNet->getAttributeCarriers()->retrieveAdditional(tag, value);
611 // replace parent additionals
612 replaceParentElements(this, parentAdditionals);
613}
614
615
616void
617GNEDemandElement::replaceDemandElementParent(SumoXMLTag tag, const std::string& value, const int parentIndex) {
618 std::vector<GNEDemandElement*> parentDemandElements = getParentDemandElements();
619 parentDemandElements[parentIndex] = myNet->getAttributeCarriers()->retrieveDemandElement(tag, value);
620 // replace parent demand elements
621 replaceParentElements(this, parentDemandElements);
622}
623
624
625void
627 std::vector<GNEDemandElement*> parents;
628 if (value.size() > 0) {
630 }
631 replaceParentElements(this, parents);
632}
633
634
635bool
637 // throw exception because this function mus be implemented in child (see GNEE3Detector)
638 throw ProcessError(StringUtils::format("Calling non-implemented function checkChildDemandElementRestriction during saving of %. It muss be reimplemented in child class", getTagStr()));
639}
640
641
642std::vector<GNEDemandElement::EdgeStopIndex>
644 std::vector<GNEDemandElement::EdgeStopIndex> edgeStopIndex;
645 // first check that this stop has parent
646 if (getParentDemandElements().size() > 0) {
647 // get path edges depending of parent
648 std::vector<GNEEdge*> pathEdges;
649 // get parent demand element
650 const auto parent = getParentDemandElements().front();
651 // continue depending of parent
652 if (parent->getTagProperty().hasAttribute(SUMO_ATTR_EDGES)) {
653 pathEdges = parent->getParentEdges();
654 } else if (parent->getTagProperty().vehicleRoute()) {
655 // get route edges
656 if (parent->getParentDemandElements().size() > 1) {
657 pathEdges = parent->getParentDemandElements().at(1)->getParentEdges();
658 }
659 } else if (parent->getTagProperty().vehicleRouteEmbedded()) {
660 // get embedded route edges
661 pathEdges = parent->getChildDemandElements().front()->getParentEdges();
662 } else {
663 // get last parent edge
664 const auto lastEdge = parent->getParentEdges().back();
665 bool stop = false;
666 const auto& pathElementSegments = myNet->getDemandPathManager()->getPathElementSegments(parent);
667 // extract all edges from pathElement parent
668 for (auto it = pathElementSegments.begin(); (it != pathElementSegments.end()) && !stop; it++) {
669 if ((*it)->getLane()) {
670 pathEdges.push_back((*it)->getLane()->getParentEdge());
671 // stop if path correspond to last edge
672 if (pathEdges.back() == lastEdge) {
673 stop = true;
674 }
675 }
676 }
677 }
678 // get all parent's stops and waypoints sorted by position
679 for (const auto& demandElement : parent->getChildDemandElements()) {
680 if (demandElement->getTagProperty().isVehicleStop()) {
681 // get stop/waypoint edge
682 GNEEdge* edge = nullptr;
683 if (demandElement->getParentAdditionals().size() > 0) {
684 edge = demandElement->getParentAdditionals().front()->getParentLanes().front()->getParentEdge();
685 } else {
686 edge = demandElement->getParentLanes().front()->getParentEdge();
687 }
688 // check if add a new edgeStopIndex or update last
689 if ((edgeStopIndex.size() > 0) && (edgeStopIndex.back().edge == edge)) {
690 edgeStopIndex.back().stops.push_back(demandElement);
691 } else {
692 edgeStopIndex.push_back(EdgeStopIndex(edge, demandElement));
693 }
694 }
695 }
696 // declare index for current stop
697 int currentEdgeStopIndex = 0;
698 for (int i = 0; (i < (int)pathEdges.size()) && (currentEdgeStopIndex < (int)edgeStopIndex.size()); i++) {
699 // check if current edge stop index is in the path
700 if (edgeStopIndex[currentEdgeStopIndex].edge == pathEdges.at(i)) {
701 edgeStopIndex[currentEdgeStopIndex].stopIndex = i;
702 currentEdgeStopIndex++;
703 } else {
704 // check if edge exist in the rest of the path
705 bool next = false;
706 for (int j = (i + 1); j < (int)pathEdges.size(); j++) {
707 if (edgeStopIndex[currentEdgeStopIndex].edge == pathEdges.at(j)) {
708 next = true;
709 }
710 }
711 if (!next) {
712 // ignore current stops (because is out of path)
713 currentEdgeStopIndex++;
714 }
715 }
716 }
717 }
718 // sort stops by position
719 for (auto& edgeStop : edgeStopIndex) {
720 if (edgeStop.stops.size() > 1) {
721 // copy all stops to a map to sort it by endPos
722 std::map<double, std::vector<GNEDemandElement*> > sortedStops;
723 for (const auto& stop : edgeStop.stops) {
724 if (sortedStops.count(stop->getAttributeDouble(SUMO_ATTR_ENDPOS)) == 0) {
725 sortedStops[stop->getAttributeDouble(SUMO_ATTR_ENDPOS)] = {stop};
726 } else {
727 sortedStops[stop->getAttributeDouble(SUMO_ATTR_ENDPOS)].push_back(stop);
728 }
729 }
730 // update stops with sorted stops
731 edgeStop.stops.clear();
732 for (const auto& sortedStop : sortedStops) {
733 edgeStop.stops.insert(edgeStop.stops.end(), sortedStop.second.begin(), sortedStop.second.end());
734 }
735 }
736 }
737 return edgeStopIndex;
738}
739
740
743 // set color depending of color active
744 switch (c.getActive()) {
745 case 0: {
746 // test for emergency vehicle
747 if (getTypeParent()->getAttribute(SUMO_ATTR_GUISHAPE) == "emergency") {
748 return RGBColor::WHITE;
749 }
750 // test for firebrigade
751 if (getTypeParent()->getAttribute(SUMO_ATTR_GUISHAPE) == "firebrigade") {
752 return RGBColor::RED;
753 }
754 // test for police car
755 if (getTypeParent()->getAttribute(SUMO_ATTR_GUISHAPE) == "police") {
756 return RGBColor::BLUE;
757 }
758 if (getTypeParent()->getAttribute(SUMO_ATTR_GUISHAPE) == "scooter") {
759 return RGBColor::WHITE;
760 }
761 // check if color was set
762 if (parameters->wasSet(VEHPARS_COLOR_SET)) {
763 return parameters->color;
764 } else {
765 // take their parent's color)
766 return getTypeParent()->getColor();
767 }
768 }
769 case 2: {
770 if (parameters->wasSet(VEHPARS_COLOR_SET)) {
771 return parameters->color;
772 } else {
773 return c.getScheme().getColor(0);
774 }
775 }
776 case 3: {
778 return getTypeParent()->getColor();
779 } else {
780 return c.getScheme().getColor(0);
781 }
782 break;
783 }
784 case 4: {
786 return getRouteParent()->getColor();
787 } else {
788 return c.getScheme().getColor(0);
789 }
790 }
791 case 5: {
792 Position p = getRouteParent()->getParentEdges().at(0)->getLanes().at(0)->getLaneShape()[0];
793 const Boundary& b = myNet->getBoundary();
794 Position center = b.getCenter();
795 double hue = 180. + atan2(center.x() - p.x(), center.y() - p.y()) * 180. / M_PI;
796 double sat = p.distanceTo(center) / center.distanceTo(Position(b.xmin(), b.ymin()));
797 return RGBColor::fromHSV(hue, sat, 1.);
798 }
799 case 6: {
800 Position p = getRouteParent()->getParentEdges().back()->getLanes().at(0)->getLaneShape()[-1];
801 const Boundary& b = myNet->getBoundary();
802 Position center = b.getCenter();
803 double hue = 180. + atan2(center.x() - p.x(), center.y() - p.y()) * 180. / M_PI;
804 double sat = p.distanceTo(center) / center.distanceTo(Position(b.xmin(), b.ymin()));
805 return RGBColor::fromHSV(hue, sat, 1.);
806 }
807 case 7: {
808 Position pb = getRouteParent()->getParentEdges().at(0)->getLanes().at(0)->getLaneShape()[0];
809 Position pe = getRouteParent()->getParentEdges().back()->getLanes().at(0)->getLaneShape()[-1];
810 const Boundary& b = myNet->getBoundary();
811 double hue = 180. + atan2(pb.x() - pe.x(), pb.y() - pe.y()) * 180. / M_PI;
812 Position minp(b.xmin(), b.ymin());
813 Position maxp(b.xmax(), b.ymax());
814 double sat = pb.distanceTo(pe) / minp.distanceTo(maxp);
815 return RGBColor::fromHSV(hue, sat, 1.);
816 }
817 case 35: { // color randomly (by pointer hash)
818 std::hash<const GNEDemandElement*> ptr_hash;
819 const double hue = (double)(ptr_hash(this) % 360); // [0-360]
820 const double sat = (double)((ptr_hash(this) / 360) % 67) / 100. + 0.33; // [0.33-1]
821 return RGBColor::fromHSV(hue, sat, 1.);
822 }
823 default: {
824 return c.getScheme().getColor(0);
825 }
826 }
827}
828
829
830std::string
832 SumoXMLTag tagDistribution = SUMO_TAG_NOTHING;
834 tagDistribution = SUMO_TAG_VTYPE_DISTRIBUTION;
835 } else if (myTagProperty.getTag() == SUMO_TAG_ROUTE) {
836 tagDistribution = SUMO_TAG_ROUTE_DISTRIBUTION;
837 } else {
838 return "";
839 }
840 // check if the current element is in the distributions
841 std::vector<std::string> distributionParents;
842 for (const auto& distribution : myNet->getAttributeCarriers()->getDemandElements().at(tagDistribution)) {
843 if (distribution.second->keyExists(this)) {
844 distributionParents.push_back(distribution.second->getID());
845 }
846 }
847 return toString(distributionParents);
848}
849
850
851void
853 std::vector<GNEEdge*> edges;
854 if (myTagProperty.isRoute()) {
855 edges = getParentEdges();
856 } else if (myTagProperty.vehicleRoute()) {
857 edges = getParentDemandElements().at(1)->getParentEdges();
858 } else if (myTagProperty.vehicleRouteEmbedded()) {
859 edges = getChildDemandElements().front()->getParentEdges();
860 } else if (myTagProperty.vehicleEdges()) {
861 edges = getParentEdges();
862 }
863 // calculate path
865 // check path size
866 if (path.size() > 0) {
867 double length = 0;
868 for (const auto& edge : path) {
869 length += edge->getNBEdge()->getFinalLength();
870 }
871 for (int i = 0; i < ((int)path.size() - 1); i++) {
872 length += path.at(i)->getLanes().front()->getLane2laneConnections().getLane2laneGeometry(path.at(i + 1)->getLanes().front()).getShape().length();
873 }
874 GUIDesigns::buildFXMenuCommand(ret, TL("Route length: ") + toString(length), nullptr, ret, MID_COPY_NAME);
875 }
876}
877
878
879void
881 // create menu pane for transform operations
882 FXMenuPane* transformOperation = new FXMenuPane(ret);
883 ret->insertMenuPaneChild(transformOperation);
884 auto reverseMenuCascade = new FXMenuCascade(ret, TL("reverse"), nullptr, transformOperation);
885 // build menu commands
886 GUIDesigns::buildFXMenuCommand(transformOperation, TLF("reverse current %", myTagProperty.getTagStr()), nullptr, myNet->getViewNet(), MID_GNE_REVERSE);
887 GUIDesigns::buildFXMenuCommand(transformOperation, TLF("Add reverse %", myTagProperty.getTagStr()), nullptr, myNet->getViewNet(), MID_GNE_ADDREVERSE);
888 // check if reverse can be added
889 if (GNERouteHandler::canReverse(this)) {
890 reverseMenuCascade->enable();
891 } else {
892 reverseMenuCascade->disable();
893 }
894}
895
896/****************************************************************************/
@ 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_COPY_TYPED_NAME
Copy typed object name - popup entry.
Definition GUIAppEnum.h:455
@ 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
GUIGlObjectType
@ GLO_VEHICLELABELS
stack and flow labels (used in netedit)
#define TL(string)
Definition MsgHandler.h:315
#define TLF(string,...)
Definition MsgHandler.h:317
const long long int VEHPARS_COLOR_SET
SumoXMLTag
Numbers representing SUMO-XML - element names.
@ SUMO_TAG_VTYPE
description of a vehicle/person/container type
@ SUMO_TAG_NOTHING
invalid tag, must be the last one
@ SUMO_TAG_ROUTE_DISTRIBUTION
distribution of a route
@ SUMO_TAG_ROUTE
begin/end of the description of a route
@ SUMO_TAG_VTYPE_DISTRIBUTION
distribution of a vehicle type
@ GNE_TAG_ROUTE_EMBEDDED
embedded route
@ SUMO_ATTR_ENDPOS
@ GNE_ATTR_VTYPE_DISTRIBUTION
vehicle type distribution
@ 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:112
double ymin() const
Returns minimum y-coordinate.
Definition Boundary.cpp:130
double xmin() const
Returns minimum x-coordinate.
Definition Boundary.cpp:118
double ymax() const
Returns maximum y-coordinate.
Definition Boundary.cpp:136
double xmax() const
Returns maximum x-coordinate.
Definition Boundary.cpp:124
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:751
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)
bool myIsTemplate
whether the current object is a template object (not drawn in the view)
static T parse(const std::string &string)
parses a value of type T from string (used for basic types: int, double, bool, etc....
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
const GNETagProperties & getTagProperty() const
get tagProperty associated with this Attribute Carrier
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
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
void replaceDemandParentEdges(const std::string &value)
replace demand parent edges
virtual void updateGeometry()=0
update pre-computed geometry information
std::vector< GNEDemandElement * > getInvalidStops() const
get invalid stops
virtual SUMOVehicleClass getVClass() const =0
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)
std::string getDistributionParents() const
get distribution in which the given element is part
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
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 setVTypeDistributionParent(const std::string &value)
set VTypeDistribution parent
void updateGLObject()
update GLObject (geometry, ID, etc.)
GNEDemandElement * getTypeParent() const
get type parent (needed because first parent can be either type or typeDistribution)
bool checkDrawSelectContour() const
check if draw select contour (blue)
void replaceDemandParentLanes(const std::string &value)
replace demand parent lanes
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
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 std::vector< GNEJunction * > & getParentJunctions() const
get parent junctions
const std::vector< GNEDemandElement * > & getChildDemandElements() const
return child demand elements
const std::vector< GNEDemandElement * > & getParentDemandElements() const
get parent demand elements
const std::vector< GNEAdditional * > & getParentAdditionals() const
get parent additionals
const std::vector< GNEEdge * > & getParentEdges() const
get parent edges
const std::vector< GNELane * > & getParentLanes() const
get parent lanes
void replaceParentElements(T *elementChild, const U &newParents)
replace parent elements
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:214
double myMoveElementLateralOffset
move element lateral offset (used by elements placed over lanes
const std::unordered_map< SumoXMLTag, std::unordered_map< const GUIGlObject *, GNEDemandElement * > > & getDemandElements() const
get demand elements
GNEAdditional * retrieveAdditional(SumoXMLTag type, const std::string &id, bool hardFail=true) const
Returns the named additional.
GNEJunction * retrieveJunction(const std::string &id, bool hardFail=true) const
get junction by id
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:697
const Boundary & getBoundary() const
returns the bounder of the network
Definition GNENet.cpp:157
GNEPathManager * getDemandPathManager()
get demand path manager
Definition GNENet.cpp:145
GNENetHelper::AttributeCarriers * getAttributeCarriers() const
get all attribute carriers used in this net
Definition GNENet.cpp:127
GNEViewNet * getViewNet() const
get view net
Definition GNENet.cpp:2163
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
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
const GUIGlObject * getGUIGlObjectFront() const
get front GUIGLObject 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
void buildSelectionACPopupEntry(GUIGLObjectPopupMenu *ret, GNEAttributeCarrier *AC)
Builds an entry which allows to (de)select the object.
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.
void updateGeometry(const PositionVector &shape)
update entire geometry
void buildShowParamsPopupEntry(GUIGLObjectPopupMenu *ret, bool addSeparator=true)
Builds an entry which allows to open the parameter window.
virtual void setMicrosimID(const std::string &newID)
Changes the microsimID of the object.
void buildCenterPopupEntry(GUIGLObjectPopupMenu *ret, bool addSeparator=true)
Builds an entry which allows to center to the object.
void buildPopupHeader(GUIGLObjectPopupMenu *ret, GUIMainWindow &app, bool addSeparator=true)
Builds the header.
GUIGlObjectType getType() const
Returns the type of the object as coded in GUIGlObjectType.
void buildPositionCopyEntry(GUIGLObjectPopupMenu *ret, const GUIMainWindow &app) const
Builds an entry which allows to copy the cursor position if geo projection is used,...
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
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:276
double distanceTo(const Position &p2) const
returns the euclidean distance in 3 dimensions
Definition Position.h:266
double x() const
Returns the x-position.
Definition Position.h:55
double y() const
Returns the y-position.
Definition Position.h:60
static const RGBColor WHITE
Definition RGBColor.h:192
static const RGBColor BLUE
Definition RGBColor.h:187
static const RGBColor GREY
Definition RGBColor.h:194
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:371
static const RGBColor DEFAULT_COLOR
The default color (for vehicle types and vehicles)
Definition RGBColor.h:199
static const RGBColor RED
named colors
Definition RGBColor.h:185
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