Eclipse SUMO - Simulation of Urban MObility
GNEDemandElement.cpp
Go to the documentation of this file.
1 /****************************************************************************/
2 // Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.org/sumo
3 // Copyright (C) 2001-2020 German Aerospace Center (DLR) and others.
4 // This program and the accompanying materials are made available under the
5 // terms of the Eclipse Public License 2.0 which is available at
6 // https://www.eclipse.org/legal/epl-2.0/
7 // This Source Code may also be made available under the following Secondary
8 // Licenses when the conditions for such availability set forth in the Eclipse
9 // Public License 2.0 are satisfied: GNU General Public License, version 2
10 // or later which is available at
11 // https://www.gnu.org/licenses/old-licenses/gpl-2.0-standalone.html
12 // SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later
13 /****************************************************************************/
18 // A abstract class for demand elements
19 /****************************************************************************/
20 #include <config.h>
21 
22 #include <netedit/GNENet.h>
23 #include <netedit/GNEViewNet.h>
24 #include <utils/gui/div/GLHelper.h>
29 
30 #include "GNEDemandElement.h"
31 
32 
33 // ===========================================================================
34 // static defintions
35 // ===========================================================================
37 
38 // ===========================================================================
39 // member method definitions
40 // ===========================================================================
41 
42 // ---------------------------------------------------------------------------
43 // GNEDemandElement - methods
44 // ---------------------------------------------------------------------------
45 
47  const std::vector<GNEJunction*>& junctionParents,
48  const std::vector<GNEEdge*>& edgeParents,
49  const std::vector<GNELane*>& laneParents,
50  const std::vector<GNEAdditional*>& additionalParents,
51  const std::vector<GNEShape*>& shapeParents,
52  const std::vector<GNETAZElement*>& TAZElementParents,
53  const std::vector<GNEDemandElement*>& demandElementParents,
54  const std::vector<GNEGenericData*>& genericDataParents) :
55  GUIGlObject(type, id),
56  GNEHierarchicalElement(net, tag, junctionParents, edgeParents, laneParents, additionalParents, shapeParents, TAZElementParents, demandElementParents, genericDataParents),
57  GNEPathElements(this),
58  myStackedLabelNumber(0) {
59 }
60 
61 
63  const std::vector<GNEJunction*>& junctionParents,
64  const std::vector<GNEEdge*>& edgeParents,
65  const std::vector<GNELane*>& laneParents,
66  const std::vector<GNEAdditional*>& additionalParents,
67  const std::vector<GNEShape*>& shapeParents,
68  const std::vector<GNETAZElement*>& TAZElementParents,
69  const std::vector<GNEDemandElement*>& demandElementParents,
70  const std::vector<GNEGenericData*>& genericDataParents) :
71  GUIGlObject(type, demandElementParent->getID()),
72  GNEHierarchicalElement(net, tag, junctionParents, edgeParents, laneParents, additionalParents, shapeParents, TAZElementParents, demandElementParents, genericDataParents),
73  GNEPathElements(this),
74  myStackedLabelNumber(0) {
75 }
76 
77 
79 
80 
81 const std::string&
83  return getMicrosimID();
84 }
85 
86 
89  return this;
90 }
91 
92 
96 }
97 
98 
102 }
103 
104 
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  return nullptr;
112  } else if (it == getChildDemandElements().begin()) {
113  return nullptr;
114  } else {
115  return *(it - 1);
116  }
117 }
118 
119 
122  // find child demand element
123  auto it = std::find(getChildDemandElements().begin(), getChildDemandElements().end(), demandElement);
124  // return element or null depending of iterator
125  if (it == getChildDemandElements().end()) {
126  return nullptr;
127  } else if (it == (getChildDemandElements().end() - 1)) {
128  return nullptr;
129  } else {
130  return *(it + 1);
131  }
132 }
133 
134 
135 std::vector<GNEEdge*>
137  std::vector<GNEEdge*> middleEdges;
138  // there are only middle edges if there is more than two edges
139  if (getParentEdges().size() > 2) {
140  // reserve middleEdges
141  middleEdges.reserve(getParentEdges().size() - 2);
142  // iterate over second and previous last parent edge
143  for (auto i = (getParentEdges().begin() + 1); i != (getParentEdges().end() - 1); i++) {
144  middleEdges.push_back(*i);
145  }
146  }
147  return middleEdges;
148 }
149 
150 
151 void
152 GNEDemandElement::updateDemandElementGeometry(const GNELane* lane, const double posOverLane) {
153  myDemandElementGeometry.updateGeometry(lane, posOverLane);
154 }
155 
156 
157 void
159  myStackedLabelNumber = stack;
160 }
161 
162 
163 void
164 GNEDemandElement::updateDemandElementSpreadGeometry(const GNELane* lane, const double posOverLane) {
165  mySpreadGeometry.updateGeometry(lane, posOverLane);
166 }
167 
168 
169 void
171  // declare extreme geometry
172  GNEGeometry::ExtremeGeometry extremeGeometry;
173  // special case for stops
174  if (myTagProperty.isVehicle()) {
175  // use depart/arrival positions as lane extremes
178  } else if (myTagProperty.isPersonPlan()) {
179  // calculate person plan start and end positions
180  extremeGeometry = calculatePersonPlanLaneStartEndPos();
181  }
182  // update geometry path for the given lane
184  // update child demand elementss
185  for (const auto& i : getChildDemandElements()) {
186  i->updatePartialGeometry(lane);
187  }
188 }
189 
190 
191 bool
193  return true;
194 }
195 
196 
197 std::string
199  return "";
200 }
201 
202 
203 void
205  throw InvalidArgument(getTagStr() + " cannot fix any problem");
206 }
207 
208 
209 void
211  throw InvalidArgument(getTagStr() + " doesn't have an demand element dialog");
212 }
213 
214 
215 std::string
217  throw InvalidArgument(getTagStr() + " doesn't have an begin time");
218 }
219 
220 
223  GUIGLObjectPopupMenu* ret = new GUIGLObjectPopupMenu(app, parent, *this);
224  // build header
225  buildPopupHeader(ret, app);
226  // build menu command for center button and copy cursor position to clipboard
228  buildPositionCopyEntry(ret, false);
229  // buld menu commands for names
230  GUIDesigns::buildFXMenuCommand(ret, "Copy " + getTagStr() + " name to clipboard", nullptr, ret, MID_COPY_NAME);
231  GUIDesigns::buildFXMenuCommand(ret, "Copy " + getTagStr() + " typed name to clipboard", nullptr, ret, MID_COPY_TYPED_NAME);
232  new FXMenuSeparator(ret);
233  // build selection and show parameters menu
236  // show option to open demand element dialog
237  if (myTagProperty.hasDialog()) {
238  GUIDesigns::buildFXMenuCommand(ret, ("Open " + getTagStr() + " Dialog").c_str(), getIcon(), &parent, MID_OPEN_ADDITIONAL_DIALOG);
239  new FXMenuSeparator(ret);
240  }
241  GUIDesigns::buildFXMenuCommand(ret, "Cursor position in view: " + toString(getPositionInView().x()) + "," + toString(getPositionInView().y()), nullptr, nullptr, 0);
242  return ret;
243 }
244 
245 
248  // Create table
249  GUIParameterTableWindow* ret = new GUIParameterTableWindow(app, *this);
250  // Iterate over attributes
251  for (const auto& i : myTagProperty) {
252  // Add attribute and set it dynamic if aren't unique
253  if (i.isUnique()) {
254  ret->mkItem(i.getAttrStr().c_str(), false, getAttribute(i.getAttr()));
255  } else {
256  ret->mkItem(i.getAttrStr().c_str(), true, getAttribute(i.getAttr()));
257  }
258  }
259  // close building
260  ret->closeBuilding();
261  return ret;
262 }
263 
264 
265 bool
266 GNEDemandElement::isValidDemandElementID(const std::string& newID) const {
267  if (SUMOXMLDefinitions::isValidVehicleID(newID) && (myNet->retrieveDemandElement(myTagProperty.getTag(), newID, false) == nullptr)) {
268  return true;
269  } else {
270  return false;
271  }
272 }
273 
274 
275 GNELane*
277  // first check if current demand element has parent edges
279  // use route edges
280  return getParentDemandElements().at(1)->getParentEdges().front()->getLaneByAllowedVClass(getVClass());
282  // check if vehicle use a embedded route
283  if (getParentDemandElements().size() == 2) {
284  return getParentDemandElements().at(1)->getParentEdges().front()->getLaneByAllowedVClass(getVClass());
285  } else {
286  return nullptr;
287  }
289  if (getChildDemandElements().size() > 0) {
290  return getChildDemandElements().front()->getParentEdges().front()->getLaneByAllowedVClass(getVClass());
291  } else {
292  return nullptr;
293  }
294  } else if (myTagProperty.personPlanStartBusStop()) {
295  return getParentAdditionals().front()->getParentLanes().front();
296  } else if (getParentEdges().size() > 0) {
298  // obtain Lane depending of attribute "departLane"
299  std::string departLane = getAttribute(SUMO_ATTR_DEPARTLANE);
300  // check depart lane
301  if ((departLane == "random") || (departLane == "free") || (departLane == "allowed") || (departLane == "best") || (departLane == "first")) {
302  return getParentEdges().front()->getLaneByAllowedVClass(getVClass());
303  }
304  // obtain index
305  const int departLaneIndex = parse<int>(getAttribute(SUMO_ATTR_DEPARTLANE));
306  // if index is correct, return lane. In other case, return nullptr;
307  if ((departLaneIndex >= 0) && (departLaneIndex < getParentEdges().front()->getNBEdge()->getNumLanes())) {
308  return getParentEdges().front()->getLanes().at(departLaneIndex);
309  } else {
310  return nullptr;
311  }
312  } else if (myTagProperty.isRide()) {
313  // special case for rides
314  return getParentEdges().front()->getLaneByDisallowedVClass(getVClass());
315  } else {
316  // in other case, always return the first allowed
317  return getParentEdges().front()->getLaneByAllowedVClass(getVClass());
318  }
319  } else {
320  return nullptr;
321  }
322 }
323 
324 
325 GNELane*
327  // first check if current demand element has parent edges
329  // use route edges
330  return getParentDemandElements().at(1)->getParentEdges().back()->getLaneByAllowedVClass(getVClass());
331  } else if (myTagProperty.personPlanEndBusStop()) {
332  // return busStop lane
333  return getParentAdditionals().back()->getParentLanes().front();
334  } else if (getParentEdges().size() > 0) {
336  // obtain Lane depending of attribute "arrivalLane"
337  std::string arrivalLane = getAttribute(SUMO_ATTR_ARRIVALLANE);
338  // check depart lane
339  if (arrivalLane == "current") {
340  return getParentEdges().back()->getLaneByAllowedVClass(getVClass());
341  }
342  // obtain index
343  const int arrivalLaneIndex = parse<int>(getAttribute(SUMO_ATTR_ARRIVALLANE));
344  // if index is correct, return lane. In other case, return nullptr;
345  if ((arrivalLaneIndex >= 0) && (arrivalLaneIndex < getParentEdges().back()->getNBEdge()->getNumLanes())) {
346  return getParentEdges().back()->getLanes().at(arrivalLaneIndex);
347  } else {
348  return nullptr;
349  }
350  } else if (myTagProperty.isRide()) {
351  // special case for rides
352  return getParentEdges().back()->getLaneByDisallowedVClass(getVClass());
353  } else {
354  // in other case, always return the first allowed
355  return getParentEdges().back()->getLaneByAllowedVClass(getVClass());
356  }
357  } else {
358  return nullptr;
359  }
360 }
361 
362 
363 const GNEEdge*
365  // set specific mode depending of tag
366  switch (myTagProperty.getTag()) {
367  // route
368  case GNE_TAG_WALK_ROUTE:
369  return getParentDemandElements().at(1)->getParentEdges().front();
370  // edges
371  case GNE_TAG_WALK_EDGES:
372  // edge->edge
376  // edge->busStop
380  return getParentEdges().front();
381  // busStop->edge
385  // busStop->busStop
389  return getParentAdditionals().front()->getParentLanes().front()->getParentEdge();
390  // stops
392  return getParentAdditionals().front()->getParentLanes().front()->getParentEdge();
394  return getParentLanes().front()->getParentEdge();
395  default:
396  return nullptr;
397  }
398 }
399 
400 
403  // declare extreme geometry
404  GNEGeometry::ExtremeGeometry extremeGeometry;
405  // get previous person Plan
406  const GNEDemandElement* previousPersonPlan = getParentDemandElements().at(0)->getPreviousChildDemandElement(this);
407  double endLanePosPreviousLane = 0;
408  // obtain previous plan
409  if (previousPersonPlan) {
410  if (previousPersonPlan->getTagProperty().personPlanEndEdge()) {
411  // get arrival position
412  endLanePosPreviousLane = previousPersonPlan->getAttributeDouble(SUMO_ATTR_ARRIVALPOS);
413  } else if (previousPersonPlan->getTagProperty().personPlanEndBusStop()) {
414  // get arrival pos (end busStop shape)
415  endLanePosPreviousLane = previousPersonPlan->getParentAdditionals().back()->getAttributeDouble(SUMO_ATTR_ENDPOS);
416  extremeGeometry.viewStartPos = previousPersonPlan->getParentAdditionals().back()->getAdditionalGeometry().getShape().back();
417  }
418  }
419  // set lane start position
421  if (previousPersonPlan) {
422  // use as startLanePos the endLanePosPreviousLane
423  extremeGeometry.laneStartPosition = endLanePosPreviousLane;
424  // obtain last allowed vehicle lane of previous person plan
425  const GNELane* lastAllowedLanePrevious = previousPersonPlan->getLastAllowedVehicleLane();
426  // check if both plans start in the same lane
427  if (lastAllowedLanePrevious) {
428  extremeGeometry.viewStartPos = lastAllowedLanePrevious->getLaneShape().positionAtOffset(extremeGeometry.laneStartPosition);
429  }
430  } else {
431  // return pedestrian departPos
432  extremeGeometry.laneStartPosition = getParentDemandElements().front()->getAttributeDouble(SUMO_ATTR_DEPARTPOS);
433  }
434  } else if (myTagProperty.personPlanStartBusStop()) {
435  // use as startLanePos the busStop end position
436  extremeGeometry.laneStartPosition = getParentAdditionals().front()->getAttributeDouble(SUMO_ATTR_ENDPOS);
437  // use as extraEndPosition the end of first busStop shape
438  extremeGeometry.viewStartPos = getParentAdditionals().front()->getAdditionalGeometry().getShape().back();
439  }
440  // set lane end position
442  // use as endLane Position the arrival position
444  } else if (myTagProperty.personPlanEndBusStop()) {
445  // use as endLanePosition the busStop start position
446  extremeGeometry.laneEndPosition = getParentAdditionals().back()->getAttributeDouble(SUMO_ATTR_STARTPOS);
447  // use as extraEndPosition the begin of last busStop shape
448  extremeGeometry.viewEndPos = getParentAdditionals().back()->getAdditionalGeometry().getShape().front();
449  }
450  // return extreme geometry
451  return extremeGeometry;
452 }
453 
454 
455 void
457  const double offsetFront, const double personPlanWidth, const RGBColor& personPlanColor) const {
458  // get inspected attribute carriers
459  const auto& inspectedACs = myNet->getViewNet()->getInspectedAttributeCarriers();
460  // get inspected person plan
461  const GNEAttributeCarrier* personPlanInspected = (inspectedACs.size() > 0) ? inspectedACs.front() : nullptr;
462  const GNEDemandElement* personParent = getParentDemandElements().front();
463  // declare flag to enable or disable draw person plan
464  bool drawPersonPlan = false;
466  // all person plan has to be drawn
467  drawPersonPlan = true;
468  } else if (myNet->getViewNet()->getDemandViewOptions().getLockedPerson() == personParent) {
469  // if person parent is locked, draw all their person plans children
470  drawPersonPlan = true;
471  } else if (personPlanInspected == personParent) {
472  // draw if we're inspecting person parent
473  drawPersonPlan = true;
474  } else if (personPlanInspected == this) {
475  // draw if we're inspecting this demand element
476  drawPersonPlan = true;
477  }
478  // check if draw person plan elements can be drawn
479  if (drawPersonPlan) {
480  // flag to check if width must be duplicated
481  const bool duplicateWidth = (personPlanInspected == this) || (personPlanInspected == personParent);
482  // get segment widtsh
483  const double segmentWidth = s.addSize.getExaggeration(s, lane) * personPlanWidth;
484  // get color
485  const RGBColor& color = drawUsingSelectColor() ? s.colorSettings.selectedPersonPlanColor : personPlanColor;
486  // Start drawing adding an gl identificator
487  glPushName(getGlID());
488  // Add a draw matrix
489  glPushMatrix();
490  // Start with the drawing of the area traslating matrix to origin
492  // iterate over segments
493  for (const auto& segment : myDemandElementSegmentGeometry) {
494  // draw partial segment
495  if (segment.isLaneSegment() && (segment.getLane() == lane)) {
496  // Set person plan color
497  GLHelper::setColor(color);
498  // draw segment depending of duplicateWidth
499  if (duplicateWidth) {
500  // draw segment geometry
501  GNEGeometry::drawSegmentGeometry(myNet->getViewNet(), segment, (2 * segmentWidth));
502  // check if shape dotted contour has to be drawn
503  if (personPlanInspected == this) {
504  GNEGeometry::drawSegmentGeometry(myNet->getViewNet(), segment, (2 * segmentWidth));
505  }
506  } else {
507  // draw segment geometry
508  GNEGeometry::drawSegmentGeometry(myNet->getViewNet(), segment, segmentWidth);
509  // check if shape dotted contour has to be drawn
510  if (personPlanInspected == this) {
511  GNEGeometry::drawSegmentGeometry(myNet->getViewNet(), segment, segmentWidth);
512  }
513  }
514  }
515  }
516  // Pop last matrix
517  glPopMatrix();
518  // Draw name if isn't being drawn for selecting
519  if (!s.drawForRectangleSelection) {
520  drawName(getCenteringBoundary().getCenter(), s.scale, s.addName);
521  }
522  // Pop name
523  glPopName();
524  // check if person plan ArrivalPos attribute
526  // obtain arrival position using last segment
528  // only draw arrival position point if isn't -1
529  if (arrivalPos != Position::INVALID) {
530  // obtain circle width
531  const double circleRadius = (duplicateWidth ? myPersonPlanArrivalPositionDiameter : (myPersonPlanArrivalPositionDiameter / 2.0));
532  const double circleWidth = circleRadius * MIN2((double)0.5, s.laneWidthExaggeration);
533  const double circleWidthSquared = circleWidth * circleWidth;
534  if (!s.drawForRectangleSelection || (myNet->getViewNet()->getPositionInformation().distanceSquaredTo2D(arrivalPos) <= (circleWidthSquared + 2))) {
535  // push draw matrix
536  glPushMatrix();
537  // Start with the drawing of the area traslating matrix to origin
539  // translate to pos and move to upper using GLO_PERSONTRIP (to avoid overlapping)
540  glTranslated(arrivalPos.x(), arrivalPos.y(), 0);
541  // Set person plan color
542  GLHelper::setColor(color);
543  // resolution of drawn circle depending of the zoom (To improve smothness)
545  // pop draw matrix
546  glPopMatrix();
547  }
548  }
549  }
550  // check if shape dotted contour has to be drawn
552  // get first and last allowed lanes
553  const GNELane* firstLane = getFirstAllowedVehicleLane();
554  const GNELane* lastLane = getLastAllowedVehicleLane();
555  // iterate over segments
556  for (const auto& segment : myDemandElementSegmentGeometry) {
557  if (segment.isLaneSegment() && (segment.getLane() == lane)) {
558  // draw partial segment
559  if (firstLane == lane) {
560  // draw front dotted contour
561  GNEGeometry::drawDottedContourLane(GNEGeometry::DottedContourType::INSPECT, s, GNEGeometry::DottedGeometry(s, segment.getShape(), false), segmentWidth, true, false);
562  } else if (lastLane == lane) {
563  // draw back dotted contour
564  GNEGeometry::drawDottedContourLane(GNEGeometry::DottedContourType::INSPECT, s, GNEGeometry::DottedGeometry(s, segment.getShape(), false), segmentWidth, false, true);
565  } else {
566  // draw dotted contour
568  }
569  }
570  }
571  }
572  }
573  // draw person parent if this is the edge first edge and this is the first plan
574  if ((getFirstPersonPlanEdge() == lane->getParentEdge()) && (personParent->getChildDemandElements().front() == this)) {
575  personParent->drawGL(s);
576  }
577 }
578 
579 
580 void
582  const double offsetFront, const double personPlanWidth, const RGBColor& personPlanColor) const {
583  // get inspected attribute carriers
584  const auto& inspectedACs = myNet->getViewNet()->getInspectedAttributeCarriers();
585  // get inspected person plan
586  const GNEAttributeCarrier* personPlanInspected = (inspectedACs.size() > 0) ? inspectedACs.front() : nullptr;
587  const GNEDemandElement* personParent = getParentDemandElements().front();
588  // declare flag to enable or disable draw person plan
589  bool drawPersonPlan = false;
591  // all person plan has to be drawn
592  drawPersonPlan = true;
593  } else if (myNet->getViewNet()->getDemandViewOptions().getLockedPerson() == personParent) {
594  // if person parent is locked, draw all their person plans children
595  drawPersonPlan = true;
596  } else if (personPlanInspected == personParent) {
597  // draw if we're inspecting person parent
598  drawPersonPlan = true;
599  } else if (personPlanInspected == this) {
600  // draw if we're inspecting this demand element
601  drawPersonPlan = true;
602  }
603  // check if draw person plan elements can be drawn
604  if (drawPersonPlan) {
605  // flag to check if width must be duplicated
606  const bool duplicateWidth = (personPlanInspected == this) || (personPlanInspected == personParent);
607  // get segment widtsh
608  const double segmentWidth = s.addSize.getExaggeration(s, fromLane) * personPlanWidth;
609  // get color
610  const RGBColor& color = drawUsingSelectColor() ? s.colorSettings.selectedPersonPlanColor : personPlanColor;
611  // Start drawing adding an gl identificator
612  glPushName(getGlID());
613  // push a draw matrix
614  glPushMatrix();
615  // Start with the drawing of the area traslating matrix to origin
617  // check if draw lane2lane connection or a red line
618  if (fromLane->getLane2laneConnections().exist(toLane)) {
619  // obtain lane2lane geometry
620  const GNEGeometry::Geometry& lane2laneGeometry = fromLane->getLane2laneConnections().getLane2laneGeometry(toLane);
621  // Set person plan color
622  GLHelper::setColor(color);
623  // draw lane2lane
624  if (duplicateWidth) {
625  GNEGeometry::drawGeometry(myNet->getViewNet(), lane2laneGeometry, (2 * segmentWidth));
626  } else {
627  GNEGeometry::drawGeometry(myNet->getViewNet(), lane2laneGeometry, segmentWidth);
628  }
629  } else {
630  // Set invalid person plan color
632  // draw line between end of first shape and first position of second shape
633  GLHelper::drawBoxLines({fromLane->getLaneShape().back(), toLane->getLaneShape().front()}, (0.5 * segmentWidth));
634  }
635  // Pop last matrix
636  glPopMatrix();
637  // Pop name
638  glPopName();
639  // check if shape dotted contour has to be drawn
641  // draw lane2lane dotted geometry
642  if (fromLane->getLane2laneConnections().exist(toLane)) {
644  }
645  }
646  }
647 }
648 
649 
650 void
652  replaceParentElements(this, parse<std::vector<GNEEdge*> >(getNet(), value));
653 }
654 
655 
656 void
658  replaceParentElements(this, parse<std::vector<GNELane*> >(getNet(), value));
659 }
660 
661 
662 void
663 GNEDemandElement::replaceFirstParentEdge(const std::string& value) {
664  std::vector<GNEEdge*> parentEdges = getParentEdges();
665  parentEdges[0] = myNet->retrieveEdge(value);
666  // replace parent edges
667  replaceParentElements(this, parentEdges);
668 }
669 
670 
671 void
672 GNEDemandElement::replaceMiddleParentEdges(const std::string& value, const bool updateChildReferences) {
673  std::vector<GNEEdge*> middleEdges = parse<std::vector<GNEEdge*> >(getNet(), value);
674  middleEdges.insert(middleEdges.begin(), getParentEdges().front());
675  middleEdges.push_back(getParentEdges().back());
676  // check if we have to update references in all childs, or simply update parent edges vector
677  if (updateChildReferences) {
678  // replace parent edges
679  replaceParentElements(this, middleEdges);
680  } else {
681  myHierarchicalContainer.setParents<std::vector<GNEEdge*> >(middleEdges);
682  }
683 }
684 
685 
686 void
687 GNEDemandElement::replaceLastParentEdge(const std::string& value) {
688  std::vector<GNEEdge*> parentEdges = getParentEdges();
689  parentEdges[(int)parentEdges.size() - 1] = myNet->retrieveEdge(value);
690  // replace parent edges
691  replaceParentElements(this, parentEdges);
692 }
693 
694 
695 void
696 GNEDemandElement::replaceAdditionalParent(SumoXMLTag tag, const std::string& value, const int parentIndex) {
697  std::vector<GNEAdditional*> parentAdditionals = getParentAdditionals();
698  parentAdditionals[parentIndex] = myNet->retrieveAdditional(tag, value);
699  // replace parent additionals
700  replaceParentElements(this, parentAdditionals);
701 }
702 
703 
704 void
705 GNEDemandElement::replaceDemandElementParent(SumoXMLTag tag, const std::string& value, const int parentIndex) {
706  std::vector<GNEDemandElement*> parentDemandElements = getParentDemandElements();
707  parentDemandElements[parentIndex] = myNet->retrieveDemandElement(tag, value);
708  // replace parent demand elements
709  replaceParentElements(this, parentDemandElements);
710 }
711 
712 
713 bool
715  // throw exception because this function mus be implemented in child (see GNEE3Detector)
716  throw ProcessError("Calling non-implemented function checkChildDemandElementRestriction during saving of " + getTagStr() + ". It muss be reimplemented in child class");
717 }
718 
719 /****************************************************************************/
@ MID_COPY_TYPED_NAME
Copy typed object name - popup entry.
Definition: GUIAppEnum.h:403
@ MID_OPEN_ADDITIONAL_DIALOG
open additional dialog (used in netedit)
Definition: GUIAppEnum.h:411
@ MID_COPY_NAME
Copy object name - popup entry.
Definition: GUIAppEnum.h:401
GUIGlObjectType
SumoXMLTag
Numbers representing SUMO-XML - element names.
@ GNE_TAG_WALK_BUSSTOP_BUSSTOP
@ GNE_TAG_PERSONTRIP_EDGE_EDGE
@ GNE_TAG_PERSONSTOP_BUSSTOP
@ GNE_TAG_RIDE_BUSSTOP_BUSSTOP
@ GNE_TAG_PERSONTRIP_BUSSTOP_EDGE
@ GNE_TAG_WALK_EDGES
@ SUMO_TAG_VEHICLE
description of a vehicle
@ GNE_TAG_FLOW_ROUTE
a flow definition using a route instead of a from-to edges route (used in NETEDIT)
@ GNE_TAG_FLOW_WITHROUTE
description of a vehicle with an embedded route (used in NETEDIT)
@ GNE_TAG_RIDE_BUSSTOP_EDGE
@ GNE_TAG_RIDE_EDGE_EDGE
@ GNE_TAG_PERSONSTOP_EDGE
@ GNE_TAG_WALK_EDGE_EDGE
@ GNE_TAG_PERSONTRIP_EDGE_BUSSTOP
@ GNE_TAG_WALK_BUSSTOP_EDGE
@ GNE_TAG_VEHICLE_WITHROUTE
@ GNE_TAG_RIDE_EDGE_BUSSTOP
@ GNE_TAG_PERSONTRIP_BUSSTOP_BUSSTOP
@ GNE_TAG_WALK_EDGE_BUSSTOP
@ GNE_TAG_WALK_ROUTE
@ SUMO_ATTR_STARTPOS
@ SUMO_ATTR_ARRIVALLANE
@ SUMO_ATTR_ENDPOS
@ SUMO_ATTR_ARRIVALPOS
@ SUMO_ATTR_DEPARTPOS
@ SUMO_ATTR_DEPARTLANE
T MIN2(T a, T b)
Definition: StdDefs.h:73
const double SUMO_const_halfLaneWidth
Definition: StdDefs.h:49
std::string toString(const T &t, std::streamsize accuracy=gPrecision)
Definition: ToString.h:44
static void setColor(const RGBColor &c)
Sets the gl-color to this value.
Definition: GLHelper.cpp:446
static void drawFilledCircle(double width, int steps=8)
Draws a filled circle around (0,0)
Definition: GLHelper.cpp:347
static void drawBoxLines(const PositionVector &geom, const std::vector< double > &rots, const std::vector< double > &lengths, double width, int cornerDetail=0, double offset=0)
Draws thick lines.
Definition: GLHelper.cpp:181
static T parse(const std::string &string)
parses a value of type T from string (used for basic types: int, double, bool, etc....
const std::string & getTagStr() const
get tag assigned to this object in string format
const GNETagProperties & getTagProperty() const
get Tag Property assigned to this object
bool drawUsingSelectColor() const
check if attribute carrier must be drawn using selecting color.
FXIcon * getIcon() const
get FXIcon associated to this AC
GNENet * myNet
pointer to net
GNENet * getNet() const
get pointer to net
const GNETagProperties & myTagProperty
the xml tag to which this attribute carrier corresponds
An Element which don't belongs to GNENet but has influency in the simulation.
GNEGeometry::SegmentGeometry myDemandElementSegmentGeometry
demand element segment geometry (also called "stacked geometry")
void replaceDemandParentEdges(const std::string &value)
replace demand parent edges
const GNEGeometry::SegmentGeometry & getDemandElementSegmentGeometry() const
get demand element segment geometry (stacked)
virtual SUMOVehicleClass getVClass() const =0
void updateDemandElementGeometry(const GNELane *lane, const double posOverLane)
update element stacked geometry (stacked)
void replaceDemandElementParent(SumoXMLTag tag, const std::string &value, const int parentIndex)
replace demand element parent
virtual std::string getBegin() const
get begin time of demand element
virtual double getAttributeDouble(SumoXMLAttr key) const =0
void drawPersonPlanPartialLane(const GUIVisualizationSettings &s, const GNELane *lane, const double offsetFront, const double personPlanWidth, const RGBColor &personPlanColor) const
draw person plan partial lane
GNEDemandElement * getNextChildDemandElement(const GNEDemandElement *demandElement) const
get next child demand element to the given demand element
GNELane * getLastAllowedVehicleLane() const
get first allowed vehicle lane
GNEGeometry::ExtremeGeometry calculatePersonPlanLaneStartEndPos() const
calculate extreme geometry
void updateDemandElementStackLabel(const int stack)
update stack label
void updatePartialGeometry(const GNELane *lane)
partial update pre-computed geometry information
void replaceLastParentEdge(const std::string &value)
replace the last parent edge
virtual std::string getAttribute(SumoXMLAttr key) const =0
GUIGlObject * getGUIGlObject()
get GUIGlObject associated with this AttributeCarrier
virtual Boundary getCenteringBoundary() const =0
Returns the boundary to which the view shall be centered in order to show the object.
virtual bool isDemandElementValid() const
check if current demand element is valid to be writed into XML (by default true, can be reimplemented...
const GNEGeometry::Geometry & getDemandElementGeometry()
get demand element geometry (stacked)
virtual std::string getDemandElementProblem() const
return a string with the current demand element problem (by default empty, can be reimplemented in ch...
void drawPersonPlanPartialJunction(const GUIVisualizationSettings &s, const GNELane *fromLane, const GNELane *toLane, const double offsetFront, const double personPlanWidth, const RGBColor &personPlanColor) const
draw person plan partial junction
void replaceDemandParentLanes(const std::string &value)
replace demand parent lanes
GNEGeometry::Geometry mySpreadGeometry
demand element spread geometry (Only used by vehicles and pedestrians)
virtual void fixDemandElementProblem()
fix demand element problem (by default throw an exception, has to be reimplemented in children)
void replaceFirstParentEdge(const std::string &value)
replace the first parent edge
int myStackedLabelNumber
stacked label number
GNEGeometry::Geometry myDemandElementGeometry
demand element geometry (also called "stacked geometry")
GUIParameterTableWindow * getParameterWindow(GUIMainWindow &app, GUISUMOAbstractView &parent)
Returns an own parameter window.
void updateDemandElementSpreadGeometry(const GNELane *lane, const double posOverLane)
update element spread geometry
virtual Position getPositionInView() const =0
Returns position of demand element in view.
virtual GUIGLObjectPopupMenu * getPopUpMenu(GUIMainWindow &app, GUISUMOAbstractView &parent)
Returns an own popup-menu.
virtual bool checkChildDemandElementRestriction() const
check restriction with the number of children
GNELane * getFirstAllowedVehicleLane() const
get first allowed vehicle lane
GNEDemandElement * getPreviousChildDemandElement(const GNEDemandElement *demandElement) const
get previous child demand element to the given demand element
void replaceAdditionalParent(SumoXMLTag tag, const std::string &value, const int parentIndex)
replace additional parent
void replaceMiddleParentEdges(const std::string &value, const bool updateChildReferences)
replace middle (via) parent edges
bool isValidDemandElementID(const std::string &newID) const
check if a new demand element ID is valid
std::vector< GNEEdge * > getViaEdges() const
get middle (via) parent edges
static const double myPersonPlanArrivalPositionDiameter
person plans arrival position radius
virtual void drawGL(const GUIVisualizationSettings &s) const =0
Draws the object.
virtual ~GNEDemandElement()
Destructor.
virtual void openDemandElementDialog()
open DemandElement Dialog
const std::string & getID() const
get ID
const GNEEdge * getFirstPersonPlanEdge() const
get first person plan edge
A road/street connecting two junctions (netedit-version)
Definition: GNEEdge.h:49
class for pack all variables related with DottedGeometry
Definition: GNEGeometry.h:187
class for NETEDIT geometries over lanes
Definition: GNEGeometry.h:76
void updateGeometry(const PositionVector &shape, double startPos=-1, double endPos=-1, const Position &extraFirstPosition=Position::INVALID, const Position &extraLastPosition=Position::INVALID)
update geometry shape
Definition: GNEGeometry.cpp:81
bool exist(const GNELane *toLane) const
check if exist a lane2lane geometry for the given tolane
const GNEGeometry::Geometry & getLane2laneGeometry(const GNELane *toLane) const
get lane2lane geometry
const GNEGeometry::DottedGeometry & getLane2laneDottedGeometry(const GNELane *toLane) const
get lane2lane dotted geometry
void setParents(const T &newParents)
set parents
const std::vector< GNEDemandElement * > & getChildDemandElements() const
return child demand elements
const std::vector< GNEDemandElement * > & getParentDemandElements() const
get parent demand elements
GNEHierarchicalContainer myHierarchicalContainer
hierarchical container with parents and children
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:45
const PositionVector & getLaneShape() const
Definition: GNELane.cpp:117
const GNEGeometry::DottedGeometry & getDottedLaneGeometry() const
get dotted lane geometry
Definition: GNELane.cpp:135
const GNEGeometry::Lane2laneConnection & getLane2laneConnections() const
get Lane2laneConnection struct
Definition: GNELane.cpp:774
GNEEdge * getParentEdge() const
get arent edge
Definition: GNELane.cpp:111
A NBNetBuilder extended by visualisation and editing capabilities.
Definition: GNENet.h:40
GNEEdge * retrieveEdge(const std::string &id, bool failHard=true) const
get edge by id
Definition: GNENet.cpp:1141
GNEAdditional * retrieveAdditional(SumoXMLTag type, const std::string &id, bool hardFail=true) const
Returns the named additional.
Definition: GNENet.cpp:2316
GNEDemandElement * retrieveDemandElement(SumoXMLTag type, const std::string &id, bool hardFail=true) const
Returns the named demand element.
Definition: GNENet.cpp:2435
GNEViewNet * getViewNet() const
get view net
Definition: GNENet.cpp:2245
An special type of Attribute carrier that owns hierarchical elements.
bool personPlanEndBusStop() const
return true if tag correspond to a person plan that starts in a busStop
bool personPlanEndEdge() const
return true if tag correspond to a person plan that starts in an edge
bool personPlanStartEdge() const
return true if tag correspond to a person plan that starts in an edge
bool isPersonPlan() const
return true if tag correspond to a person plan
bool isVehicle() const
return true if tag correspond to a vehicle element
bool personPlanStartBusStop() const
return true if tag correspond to a person plan that starts in a busStop
SumoXMLTag getTag() const
get Tag vinculated with this attribute Property
bool isRide() const
return true if tag correspond to a ride element
bool hasDialog() const
return true if tag correspond to an element that can be edited using a dialog
bool hasAttribute(SumoXMLAttr attr) const
check if current TagProperties owns the attribute "attr"
const std::vector< GNEAttributeCarrier * > & getInspectedAttributeCarriers() const
get inspected attribute carriers
void buildSelectionACPopupEntry(GUIGLObjectPopupMenu *ret, GNEAttributeCarrier *AC)
Builds an entry which allows to (de)select the object.
Definition: GNEViewNet.cpp:368
bool isAttributeCarrierInspected(const GNEAttributeCarrier *AC) const
check if attribute carrier is being inspected
void drawTranslateFrontAttributeCarrier(const GNEAttributeCarrier *AC, GUIGlObjectType objectType, const double extraOffset=0)
draw front attributeCarrier
const GNEViewNetHelper::DemandViewOptions & getDemandViewOptions() const
get demand view options
Definition: GNEViewNet.cpp:485
static FXMenuCommand * buildFXMenuCommand(FXComposite *p, const std::string &text, FXIcon *icon, FXObject *tgt, FXSelector sel)
build menu command
Definition: GUIDesigns.cpp:40
The popup menu of a globject.
void buildPositionCopyEntry(GUIGLObjectPopupMenu *ret, bool addSeparator=true)
Builds an entry which allows to copy the cursor position if geo projection is used,...
virtual const std::string & getMicrosimID() const
Returns the id of the object as known to microsim.
void buildShowParamsPopupEntry(GUIGLObjectPopupMenu *ret, bool addSeparator=true)
Builds an entry which allows to open the parameter window.
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.
GUIGlID getGlID() const
Returns the numerical id of the object.
void drawName(const Position &pos, const double scale, const GUIVisualizationTextSettings &settings, const double angle=0) const
draw name of item
A window containing a gl-object's parameter.
void mkItem(const char *name, bool dynamic, ValueSource< T > *src)
Adds a row which obtains its value from a ValueSource.
void closeBuilding(const Parameterised *p=0)
Closes the building of the table.
Position getPositionInformation() const
Returns the cursor's x/y position within the network.
Stores the information about how to visualize structures.
GUIVisualizationTextSettings addName
bool drawForRectangleSelection
whether drawing is performed for the purpose of selecting objects using a rectangle
GUIVisualizationSizeSettings addSize
double laneWidthExaggeration
The lane exaggeration (upscale thickness)
bool drawDottedContour() const
check if dotted contour can be drawn
GUIVisualizationColorSettings colorSettings
color settings
double scale
information about a lane's width (temporary, used for a single view)
int getCircleResolution() const
function to calculate circle resolution for all circles drawn in drawGL(...) functions
A point in 2D or 3D with translation and scaling methods.
Definition: Position.h:36
double distanceSquaredTo2D(const Position &p2) const
returns the square of the distance to another position (Only using x and y positions)
Definition: Position.h:246
static const Position INVALID
used to indicate that a position is valid
Definition: Position.h:282
double x() const
Returns the x-position.
Definition: Position.h:54
double y() const
Returns the y-position.
Definition: Position.h:59
Position positionAtOffset(double pos, double lateralOffset=0) const
Returns the position at the given length.
static const RGBColor RED
named colors
Definition: RGBColor.h:180
static bool isValidVehicleID(const std::string &value)
whether the given string is a valid id for a vehicle or flow
struct for variables used in Geometry extremes
Definition: GNEGeometry.h:58
double laneEndPosition
arrival position over lane
Definition: GNEGeometry.h:66
Position viewEndPos
end position over view
Definition: GNEGeometry.h:72
double laneStartPosition
depart position over lane
Definition: GNEGeometry.h:63
Position viewStartPos
start position over view
Definition: GNEGeometry.h:69
struct for pack all variables related with geometry of elemements divided in segments
Definition: GNEGeometry.h:261
const Position & getLastPosition() const
get first position (or Invalid position if segments are empty)
static void drawDottedContourLane(const DottedContourType type, const GUIVisualizationSettings &s, const DottedGeometry &dottedGeometry, const double width, const bool drawFirstExtrem, const bool drawLastExtrem)
draw dotted contour for the given dottedGeometry (used by lanes, routes, etc.)
static void updateGeometricPath(GNEGeometry::SegmentGeometry &segmentGeometry, const GNELane *lane, GNEGeometry::ExtremeGeometry &extremeGeometry)
calculate route between edges
static void drawSegmentGeometry(const GNEViewNet *viewNet, const SegmentGeometry::Segment &segment, const double width)
draw geometry segment
static void drawGeometry(const GNEViewNet *viewNet, const Geometry &geometry, const double width)
draw geometry
bool showAllPersonPlans() const
check all person plans has to be show
const GNEDemandElement * getLockedPerson() const
get locked person
RGBColor selectedPersonPlanColor
person plan selection color (Rides, Walks, personStops...)
double getExaggeration(const GUIVisualizationSettings &s, const GUIGlObject *o, double factor=20) const
return the drawing size including exaggeration and constantSize values