Eclipse SUMO - Simulation of Urban MObility
GNEHierarchicalChildElements.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 representation of additional elements
19 /****************************************************************************/
20 #include <config.h>
21 
22 #include <netedit/GNEViewNet.h>
29 #include <netedit/GNENet.h>
30 #include <netedit/GNEViewParent.h>
31 #include <utils/gui/div/GLHelper.h>
33 
35 
36 // ===========================================================================
37 // member method definitions
38 // ===========================================================================
39 
41  const std::vector<GNEJunction*>& childJunctions,
42  const std::vector<GNEEdge*>& childEdges,
43  const std::vector<GNELane*>& childLanes,
44  const std::vector<GNEAdditional*>& childAdditionals,
45  const std::vector<GNEShape*>& childShapes,
46  const std::vector<GNETAZElement*>& childTAZElements,
47  const std::vector<GNEDemandElement*>& childDemandElements,
48  const std::vector<GNEGenericData*>& childGenericDataElements) :
49  myChildConnections(this),
50  myChildJunctions(childJunctions),
51  myChildEdges(childEdges),
52  myChildLanes(childLanes),
53  myChildAdditionals(childAdditionals),
54  myChildShapes(childShapes),
55  myChildTAZElements(childTAZElements),
56  myChildDemandElements(childDemandElements),
57  myChildGenericDataElements(childGenericDataElements),
58  myAC(AC) {
59  // fill SortedChildDemandElementsByType with all demand element tags (it's needed because getChildDemandElementsSortedByType(...) function is constant
60  auto listOfTags = GNEAttributeCarrier::allowedTagsByCategory(GNETagProperties::TagType::DEMANDELEMENT, false);
61  for (const auto& tag : listOfTags) {
62  myDemandElementsByType[tag] = {};
63  }
64 }
65 
66 
68 
69 
70 const Position&
72  for (const auto& childConnection : myChildConnections.symbolsPositionAndRotation) {
73  if (childConnection.getLane() == lane) {
74  return childConnection.getPosition();
75  }
76  }
77  throw ProcessError("Lane doesn't exist");
78 }
79 
80 
81 double
83  for (const auto& childConnection : myChildConnections.symbolsPositionAndRotation) {
84  if (childConnection.getLane() == lane) {
85  return childConnection.getRotation();
86  }
87  }
88  throw ProcessError("Lane doesn't exist");
89 }
90 
91 
92 void
95 }
96 
97 
98 void
99 GNEHierarchicalChildElements::drawChildConnections(const GUIVisualizationSettings& s, const GUIGlObjectType GLTypeParent, const double exaggeration) const {
100  // first check if connections can be drawn
101  if (!s.drawForRectangleSelection && (exaggeration > 0)) {
102  myChildConnections.drawConnection(s, GLTypeParent, exaggeration);
103  }
104 }
105 
106 
107 void
109  // first check if connections can be drawn
110  if (!s.drawForRectangleSelection && (exaggeration > 0)) {
111  myChildConnections.drawDottedConnection(s, exaggeration);
112  }
113 }
114 
115 
116 template <> void
118  // Check that edge is valid and doesn't exist previously
119  if (edge == nullptr) {
120  throw InvalidArgument("Trying to add an empty child edge in " + myAC->getTagStr() + " with ID='" + myAC->getID() + "'");
121  } else {
122  myChildEdges.push_back(edge);
123  }
124 }
125 
126 
127 template <> void
129  // Check if lane is valid
130  if (lane == nullptr) {
131  throw InvalidArgument("Trying to add an empty child lane in " + myAC->getTagStr() + " with ID='" + myAC->getID() + "'");
132  } else {
133  myChildLanes.push_back(lane);
134  // update connections geometry
136  }
137 }
138 
139 
140 template <> void
142  // Check if additional is valid
143  if (additional == nullptr) {
144  throw InvalidArgument("Trying to add an empty child additional in " + myAC->getTagStr() + " with ID='" + myAC->getID() + "'");
145  } else {
146  // add it in child additional container
147  myChildAdditionals.push_back(additional);
148  // Check if children has to be sorted automatically
151  }
152  // update parent additional after add additional (note: by default non-implemented)
154  }
155 }
156 
157 
158 template <> void
160  // Check that shape is valid and doesn't exist previously
161  if (shape == nullptr) {
162  throw InvalidArgument("Trying to add an empty child shape in " + myAC->getTagStr() + " with ID='" + myAC->getID() + "'");
163  } else if (std::find(myChildShapes.begin(), myChildShapes.end(), shape) != myChildShapes.end()) {
164  throw InvalidArgument("Trying to add a duplicate child shape in " + myAC->getTagStr() + " with ID='" + myAC->getID() + "'");
165  } else {
166  myChildShapes.push_back(shape);
167  // update connections geometry
169  }
170 }
171 
172 
173 template <> void
175  // Check that TAZElement is valid and doesn't exist previously
176  if (TAZElement == nullptr) {
177  throw InvalidArgument("Trying to add an empty child TAZElement in " + myAC->getTagStr() + " with ID='" + myAC->getID() + "'");
178  } else if (std::find(myChildTAZElements.begin(), myChildTAZElements.end(), TAZElement) != myChildTAZElements.end()) {
179  throw InvalidArgument("Trying to add a duplicate child TAZElement in " + myAC->getTagStr() + " with ID='" + myAC->getID() + "'");
180  } else {
181  myChildTAZElements.push_back(TAZElement);
182  // update connections geometry
184  }
185 }
186 
187 
188 template <> void
190  // Check if demand element is valid
191  if (demandElement == nullptr) {
192  throw InvalidArgument("Trying to add an empty child demand element in " + myAC->getTagStr() + " with ID='" + myAC->getID() + "'");
193  } else {
194  // add it in demandElement child container
195  myChildDemandElements.push_back(demandElement);
196  // add it also in SortedChildDemandElementsByType container
197  myDemandElementsByType.at(demandElement->getTagProperty().getTag()).push_back(demandElement);
198  // Check if children has to be sorted automatically
201  }
202  }
203 }
204 
205 template <> void
207  // Check if demand element is valid
208  if (genericDataElement == nullptr) {
209  throw InvalidArgument("Trying to add an empty child generic data element in " + myAC->getTagStr() + " with ID='" + myAC->getID() + "'");
210  } else {
211  // add it in generic data element child container
212  myChildGenericDataElements.push_back(genericDataElement);
213  }
214 }
215 
216 
217 template <> void
219  // Check that edge is valid and exist previously
220  if (edge == nullptr) {
221  throw InvalidArgument("Trying to remove an empty child edge in " + myAC->getTagStr() + " with ID='" + myAC->getID() + "'");
222  } else if (std::find(myChildEdges.begin(), myChildEdges.end(), edge) == myChildEdges.end()) {
223  throw InvalidArgument("Trying to remove a non previously inserted child edge in " + myAC->getTagStr() + " with ID='" + myAC->getID() + "'");
224  } else {
225  myChildEdges.erase(std::find(myChildEdges.begin(), myChildEdges.end(), edge));
226  // update connections geometry
228  }
229 }
230 
231 
232 template <> void
234  // Check if lane is valid
235  if (lane == nullptr) {
236  throw InvalidArgument("Trying to remove an empty child lane in " + myAC->getTagStr() + " with ID='" + myAC->getID() + "'");
237  } else {
238  myChildLanes.erase(std::find(myChildLanes.begin(), myChildLanes.end(), lane));
239  // update connections geometry
241  }
242 }
243 
244 
245 template <> void
247  // First check that additional was already inserted
248  auto it = std::find(myChildAdditionals.begin(), myChildAdditionals.end(), additional);
249  if (it == myChildAdditionals.end()) {
250  throw ProcessError(additional->getTagStr() + " with ID='" + additional->getID() + "' doesn't exist in " + myAC->getTagStr() + " with ID='" + myAC->getID() + "'");
251  } else {
252  myChildAdditionals.erase(it);
253  // Check if children has to be sorted automatically
256  }
257  // update parent additional after add additional (note: by default non-implemented)
259  }
260 }
261 
262 
263 template <> void
265  // Check that shape is valid and exist previously
266  if (shape == nullptr) {
267  throw InvalidArgument("Trying to remove an empty child shape in " + myAC->getTagStr() + " with ID='" + myAC->getID() + "'");
268  } else if (std::find(myChildShapes.begin(), myChildShapes.end(), shape) == myChildShapes.end()) {
269  throw InvalidArgument("Trying to remove a non previously inserted child shape in " + myAC->getTagStr() + " with ID='" + myAC->getID() + "'");
270  } else {
271  myChildShapes.erase(std::find(myChildShapes.begin(), myChildShapes.end(), shape));
272  // update connections geometry
274  }
275 }
276 
277 
278 template <> void
280  // Check that TAZElement is valid and exist previously
281  if (TAZElement == nullptr) {
282  throw InvalidArgument("Trying to remove an empty child TAZElement in " + myAC->getTagStr() + " with ID='" + myAC->getID() + "'");
283  } else if (std::find(myChildTAZElements.begin(), myChildTAZElements.end(), TAZElement) == myChildTAZElements.end()) {
284  throw InvalidArgument("Trying to remove a non previously inserted child TAZElement in " + myAC->getTagStr() + " with ID='" + myAC->getID() + "'");
285  } else {
286  myChildTAZElements.erase(std::find(myChildTAZElements.begin(), myChildTAZElements.end(), TAZElement));
287  // update connections geometry
289  }
290 }
291 
292 
293 template <> void
295  // First check that demandElement was already inserted
296  auto it = std::find(myChildDemandElements.begin(), myChildDemandElements.end(), demandElement);
297  auto itByType = std::find(myDemandElementsByType.at(demandElement->getTagProperty().getTag()).begin(), myDemandElementsByType.at(demandElement->getTagProperty().getTag()).end(), demandElement);
298  if (it == myChildDemandElements.end()) {
299  throw ProcessError(demandElement->getTagStr() + " with ID='" + demandElement->getID() + "' doesn't exist in " + myAC->getTagStr() + " with ID='" + myAC->getID() + "'");
300  } else {
301  // first check if element is duplicated in vector
302  bool singleElement = std::count(myChildDemandElements.begin(), myChildDemandElements.end(), demandElement) == 1;
303  myChildDemandElements.erase(it);
304  // only remove it from mySortedChildDemandElementsByType if is a single element
305  if (singleElement && (itByType != myDemandElementsByType.at(demandElement->getTagProperty().getTag()).end())) {
306  myDemandElementsByType.at(demandElement->getTagProperty().getTag()).erase(itByType);
307  }
308  // Check if children has to be sorted automatically
311  }
312  }
313 }
314 
315 template <> void
317  // First check that genericDataElement was already inserted
318  auto it = std::find(myChildGenericDataElements.begin(), myChildGenericDataElements.end(), genericDataElement);
319  if (it == myChildGenericDataElements.end()) {
320  throw ProcessError(genericDataElement->getTagStr() + " with ID='" + genericDataElement->getID() + "' doesn't exist in " + myAC->getTagStr() + " with ID='" + myAC->getID() + "'");
321  } else {
322  // remove it from child demand elements
323  myChildGenericDataElements.erase(it);
324  }
325 }
326 
327 
328 const std::vector<GNEEdge*>&
330  return myChildEdges;
331 }
332 
333 
334 const std::vector<GNELane*>&
336  return myChildLanes;
337 }
338 
339 
340 const std::vector<GNEAdditional*>&
342  return myChildAdditionals;
343 }
344 
345 
346 const std::vector<GNEShape*>&
348  return myChildShapes;
349 }
350 
351 
352 const std::vector<GNETAZElement*>&
354  return myChildTAZElements;
355 }
356 
357 
358 const std::vector<GNEDemandElement*>&
360  return myChildDemandElements;
361 }
362 
363 
364 const std::vector<GNEGenericData*>&
367 }
368 
369 
370 void
373  // we need to sort Entry/Exits due additional.xds model
374  std::vector<GNEAdditional*> sortedEntryExits;
375  // obtain all entrys
376  for (const auto& additional : myChildAdditionals) {
377  if (additional->getTagProperty().getTag() == SUMO_TAG_DET_ENTRY) {
378  sortedEntryExits.push_back(additional);
379  }
380  }
381  // obtain all exits
382  for (const auto& additional : myChildAdditionals) {
383  if (additional->getTagProperty().getTag() == SUMO_TAG_DET_EXIT) {
384  sortedEntryExits.push_back(additional);
385  }
386  }
387  // change myChildAdditionals for sortedEntryExits
388  if (sortedEntryExits.size() == myChildAdditionals.size()) {
389  myChildAdditionals = sortedEntryExits;
390  } else {
391  throw ProcessError("Some child additional were lost during sorting");
392  }
393  } else if (myAC->getTagProperty().getTag() == SUMO_TAG_TAZ) {
394  // we need to sort Entry/Exits due additional.xds model
395  std::vector<GNEAdditional*> sortedTAZSourceSink;
396  // obtain all TAZSources
397  for (const auto& additional : myChildAdditionals) {
398  if (additional->getTagProperty().getTag() == SUMO_TAG_TAZSOURCE) {
399  sortedTAZSourceSink.push_back(additional);
400  }
401  }
402  // obtain all TAZSinks
403  for (const auto& additional : myChildAdditionals) {
404  if (additional->getTagProperty().getTag() == SUMO_TAG_TAZSINK) {
405  sortedTAZSourceSink.push_back(additional);
406  }
407  }
408  // change myChildAdditionals for sortedEntryExits
409  if (sortedTAZSourceSink.size() == myChildAdditionals.size()) {
410  myChildAdditionals = sortedTAZSourceSink;
411  } else {
412  throw ProcessError("Some child additional were lost during sorting");
413  }
414  } else {
415  // declare a vector to keep sorted children
416  std::vector<std::pair<std::pair<double, double>, GNEAdditional*> > sortedChildren;
417  // iterate over child additional
418  for (const auto& additional : myChildAdditionals) {
419  sortedChildren.push_back(std::make_pair(std::make_pair(0., 0.), additional));
420  // set begin/start attribute
421  if (additional->getTagProperty().hasAttribute(SUMO_ATTR_TIME) && GNEAttributeCarrier::canParse<double>(additional->getAttribute(SUMO_ATTR_TIME))) {
422  sortedChildren.back().first.first = additional->getAttributeDouble(SUMO_ATTR_TIME);
423  } else if (additional->getTagProperty().hasAttribute(SUMO_ATTR_BEGIN) && GNEAttributeCarrier::canParse<double>(additional->getAttribute(SUMO_ATTR_BEGIN))) {
424  sortedChildren.back().first.first = additional->getAttributeDouble(SUMO_ATTR_BEGIN);
425  }
426  // set end attribute
427  if (additional->getTagProperty().hasAttribute(SUMO_ATTR_END) && GNEAttributeCarrier::canParse<double>(additional->getAttribute(SUMO_ATTR_END))) {
428  sortedChildren.back().first.second = additional->getAttributeDouble(SUMO_ATTR_END);
429  } else {
430  sortedChildren.back().first.second = sortedChildren.back().first.first;
431  }
432  }
433  // sort children
434  std::sort(sortedChildren.begin(), sortedChildren.end());
435  // make sure that number of sorted children is the same as the child additional
436  if (sortedChildren.size() == myChildAdditionals.size()) {
437  myChildAdditionals.clear();
438  for (auto i : sortedChildren) {
439  myChildAdditionals.push_back(i.second);
440  }
441  } else {
442  throw ProcessError("Some child additional were lost during sorting");
443  }
444  }
445 }
446 
447 
448 bool
450  // declare a vector to keep sorted children
451  std::vector<std::pair<std::pair<double, double>, GNEAdditional*> > sortedChildren;
452  // iterate over child additional
453  for (const auto& additional : myChildAdditionals) {
454  sortedChildren.push_back(std::make_pair(std::make_pair(0., 0.), additional));
455  // set begin/start attribute
456  if (additional->getTagProperty().hasAttribute(SUMO_ATTR_TIME) && GNEAttributeCarrier::canParse<double>(additional->getAttribute(SUMO_ATTR_TIME))) {
457  sortedChildren.back().first.first = additional->getAttributeDouble(SUMO_ATTR_TIME);
458  } else if (additional->getTagProperty().hasAttribute(SUMO_ATTR_BEGIN) && GNEAttributeCarrier::canParse<double>(additional->getAttribute(SUMO_ATTR_BEGIN))) {
459  sortedChildren.back().first.first = additional->getAttributeDouble(SUMO_ATTR_BEGIN);
460  }
461  // set end attribute
462  if (additional->getTagProperty().hasAttribute(SUMO_ATTR_END) && GNEAttributeCarrier::canParse<double>(additional->getAttribute(SUMO_ATTR_END))) {
463  sortedChildren.back().first.second = additional->getAttributeDouble(SUMO_ATTR_END);
464  } else {
465  sortedChildren.back().first.second = sortedChildren.back().first.first;
466  }
467  }
468  // sort children
469  std::sort(sortedChildren.begin(), sortedChildren.end());
470  // make sure that number of sorted children is the same as the child additional
471  if (sortedChildren.size() == myChildAdditionals.size()) {
472  if (sortedChildren.size() <= 1) {
473  return true;
474  } else {
475  // check overlapping
476  for (int i = 0; i < (int)sortedChildren.size() - 1; i++) {
477  if (sortedChildren.at(i).first.second > sortedChildren.at(i + 1).first.first) {
478  return false;
479  }
480  }
481  }
482  return true;
483  } else {
484  throw ProcessError("Some child additional were lost during sorting");
485  }
486 }
487 
488 
489 const std::vector<GNEDemandElement*>&
491  return myDemandElementsByType.at(tag);
492 }
493 
494 
495 void
497  // by default empty
498 }
499 
500 
501 bool
503  return true;
504 }
505 
506 
509  // find child demand element
510  auto it = std::find(myChildDemandElements.begin(), myChildDemandElements.end(), demandElement);
511  // return element or null depending of iterator
512  if (it == myChildDemandElements.end()) {
513  return nullptr;
514  } else if (it == myChildDemandElements.begin()) {
515  return nullptr;
516  } else {
517  return *(it - 1);
518  }
519 }
520 
521 
524  // find child demand element
525  auto it = std::find(myChildDemandElements.begin(), myChildDemandElements.end(), demandElement);
526  // return element or null depending of iterator
527  if (it == myChildDemandElements.end()) {
528  return nullptr;
529  } else if (it == (myChildDemandElements.end() - 1)) {
530  return nullptr;
531  } else {
532  return *(it + 1);
533  }
534 }
535 
536 
537 void
539  // by default nothing to do
540 }
541 
542 void
544  // by default nothing to do
545 }
546 
547 
548 void
549 GNEHierarchicalChildElements::changeChildEdges(GNEAdditional* elementChild, const std::string& newEdgeIDs) {
550  // remove demandElement of child edges
551  for (const auto& edge : myChildEdges) {
552  edge->removeParentElement(elementChild);
553  }
554  // obtain new child edges (note: it can be empty)
555  myChildEdges = GNEAttributeCarrier::parse<std::vector<GNEEdge*> >(elementChild->getNet(), newEdgeIDs);
556  // add demandElement into parent edges
557  for (const auto& edge : myChildEdges) {
558  edge->addParentElement(elementChild);
559  }
560  // update connections geometry
562 }
563 
564 
565 void
566 GNEHierarchicalChildElements::changeChildLanes(GNEAdditional* elementChild, const std::string& newLaneIDs) {
567  // remove demandElement of child lanes
568  for (const auto& lane : myChildLanes) {
569  lane->removeParentElement(elementChild);
570  }
571  // obtain new child lanes (note: it can be empty)
572  myChildLanes = GNEAttributeCarrier::parse<std::vector<GNELane*> >(elementChild->getNet(), newLaneIDs);
573  // add demandElement into parent lanes
574  for (const auto& lane : myChildLanes) {
575  lane->addParentElement(elementChild);
576  }
577  // update connections geometry
579 }
580 
581 // ---------------------------------------------------------------------------
582 // GNEHierarchicalChildElements::ChildConnections - methods
583 // ---------------------------------------------------------------------------
584 
586  myLane(lane),
587  myRotation(0) {
588  // set position and length depending of shape's lengt
589  if (lane->getLaneShape().length() - 6 > 0) {
592  } else {
595  }
596 }
597 
598 
599 const GNELane*
601  return myLane;
602 }
603 
604 const Position&
606  return myPosition;
607 }
608 
609 
610 double
612  return myRotation;
613 }
614 
615 
617  myLane(nullptr),
618  myRotation(0) {
619 }
620 
621 
623  myHierarchicalElement(hierarchicalElement) {}
624 
625 
626 void
628  // first clear containers
629  connectionsGeometries.clear();
631  // calculate position and rotation of every simbol for every edge
632  for (const auto& edge : myHierarchicalElement->myChildEdges) {
633  for (const auto& lane : edge->getLanes()) {
635  }
636  }
637  // calculate position and rotation of every symbol for every lane
638  for (const auto& lane : myHierarchicalElement->myChildLanes) {
640  }
641  // calculate position for every child additional
642  for (const auto& additional : myHierarchicalElement->myChildAdditionals) {
643  // check that additional position is different of parent position
644  if (additional->getPositionInView() != myHierarchicalElement->getPositionInView()) {
645  // create connection shape
646  std::vector<Position> connectionShape;
647  const double A = std::abs(additional->getPositionInView().x() - myHierarchicalElement->getPositionInView().x());
648  const double B = std::abs(additional->getPositionInView().y() - myHierarchicalElement->getPositionInView().y());
649  // Set positions of connection's vertex. Connection is build from Entry to E3
650  connectionShape.push_back(additional->getPositionInView());
651  if (myHierarchicalElement->getPositionInView().x() > additional->getPositionInView().x()) {
652  if (myHierarchicalElement->getPositionInView().y() > additional->getPositionInView().y()) {
653  connectionShape.push_back(Position(additional->getPositionInView().x() + A, additional->getPositionInView().y()));
654  } else {
655  connectionShape.push_back(Position(additional->getPositionInView().x(), additional->getPositionInView().y() - B));
656  }
657  } else {
658  if (myHierarchicalElement->getPositionInView().y() > additional->getPositionInView().y()) {
659  connectionShape.push_back(Position(additional->getPositionInView().x(), additional->getPositionInView().y() + B));
660  } else {
661  connectionShape.push_back(Position(additional->getPositionInView().x() - A, additional->getPositionInView().y()));
662  }
663  }
664  connectionShape.push_back(myHierarchicalElement->getPositionInView());
665  // declare Geometry
666  GNEGeometry::Geometry geometry;
667  // update geometry with connectino shape
668  geometry.updateGeometry(connectionShape);
669  // add geometry in connectionsGeometry
670  connectionsGeometries.push_back(geometry);
671  }
672  }
673  // calculate geometry for connections between parent and children
674  for (const auto& symbol : symbolsPositionAndRotation) {
675  // create connection shape
676  std::vector<Position> connectionShape;
677  const double A = std::abs(symbol.getPosition().x() - myHierarchicalElement->getPositionInView().x());
678  const double B = std::abs(symbol.getPosition().y() - myHierarchicalElement->getPositionInView().y());
679  // Set positions of connection's vertex. Connection is build from Entry to E3
680  connectionShape.push_back(symbol.getPosition());
681  if (myHierarchicalElement->getPositionInView().x() > symbol.getPosition().x()) {
682  if (myHierarchicalElement->getPositionInView().y() > symbol.getPosition().y()) {
683  connectionShape.push_back(Position(symbol.getPosition().x() + A, symbol.getPosition().y()));
684  } else {
685  connectionShape.push_back(Position(symbol.getPosition().x(), symbol.getPosition().y() - B));
686  }
687  } else {
688  if (myHierarchicalElement->getPositionInView().y() > symbol.getPosition().y()) {
689  connectionShape.push_back(Position(symbol.getPosition().x(), symbol.getPosition().y() + B));
690  } else {
691  connectionShape.push_back(Position(symbol.getPosition().x() - A, symbol.getPosition().y()));
692  }
693  }
694  connectionShape.push_back(myHierarchicalElement->getPositionInView());
695  // declare Geometry
696  GNEGeometry::Geometry geometry;
697  // update geometry with connectino shape
698  geometry.updateGeometry(connectionShape);
699  // add geometry in connectionsGeometry
700  connectionsGeometries.push_back(geometry);
701  }
702 }
703 
704 
705 void
707  // Iterate over myConnectionPositions
708  for (const auto& connectionGeometry : connectionsGeometries) {
709  // Add a draw matrix
710  glPushMatrix();
711  // traslate in the Z axis
712  glTranslated(0, 0, parentType - 0.01);
713  // Set color of the base
715  // Draw box lines
716  GLHelper::drawBoxLines(connectionGeometry.getShape(), connectionGeometry.getShapeRotations(), connectionGeometry.getShapeLengths(), exaggeration * 0.1);
717  // Pop draw matrix
718  glPopMatrix();
719  }
720 }
721 
722 
723 void
725  // Iterate over myConnectionPositions
726  for (const auto& connectionGeometry : connectionsGeometries) {
727  // calculate dotted geometry
728  GNEGeometry::DottedGeometry dottedGeometry(s, connectionGeometry.getShape(), false);
729  // change default width
730  dottedGeometry.setWidth(0.1);
731  // use drawDottedContourLane to draw it
732  GNEGeometry::drawDottedContourLane(true, s, dottedGeometry, exaggeration * 0.1, false, false);
733  }
734 }
735 
736 
737 /****************************************************************************/
void changeChildEdges(GNEAdditional *elementChild, const std::string &newEdgeIDs)
change child edges of an additional
const std::vector< GNEShape * > & getChildShapes() const
get child shapes
double rotationDegreeAtOffset(double pos) const
Returns the rotation at the given length.
std::vector< GNEGeometry::Geometry > connectionsGeometries
geometry connections between parents an their children
SumoXMLTag
Numbers representing SUMO-XML - element names.
virtual Position getPositionInView() const =0
Returns position of hierarchical element in view.
static const RGBColor childConnections
color for child connections between parents and child elements
a source within a district (connection road)
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
GUIGlObjectType
class for NETEDIT geometries over lanes
Definition: GNEGeometry.h:76
const Position & getChildPosition(const GNELane *lane)
get child position calculated in ChildConnections
void updateChildConnections()
update child connections
An Element which don&#39;t belongs to GNENet but has influency in the simulation.
SumoXMLTag getTag() const
get Tag vinculated with this attribute Property
void changeChildLanes(GNEAdditional *elementChild, const std::string &newEdgeIDs)
change child edges of an additional
a traffic assignment zone
bool checkChildAdditionalsOverlapping() const
check if children are overlapped (Used by Rerouters)
const GNEAttributeCarrier * myAC
pointer to AC (needed to avoid diamond problem)
Stores the information about how to visualize structures.
double y() const
Returns the y-position.
Definition: Position.h:59
bool checkChildDemandElementsOverlapping() const
check if childs demand elements are overlapped
GNEHierarchicalChildElements * myHierarchicalElement
pointer to hierarchical element parent
An Element which don&#39;t belongs to GNENet but has influency in the simulation.
Definition: GNETAZElement.h:46
double x() const
Returns the x-position.
Definition: Position.h:54
weights: time range begin
const std::string & getID() const
get ID
ChildConnections myChildConnections
variable ChildConnections
const std::string & getID() const
get ID
This lane is powered by an underlying GNEEdge and basically knows how to draw itself.
Definition: GNELane.h:45
std::vector< GNEGenericData * > myChildGenericDataElements
vector with the generic data elements children
std::vector< GNELane * > myChildLanes
vector with the child lanes
void setWidth(const double width)
change default width
static std::vector< SumoXMLTag > allowedTagsByCategory(const int tagPropertyCategory, const bool onlyDrawables)
get tags of all editable element types using TagProperty Type (NetworkEditMode::NETWORKELEMENT, ADDITIONALELEMENT, etc.)
class for pack all variables related with DottedGeometry
Definition: GNEGeometry.h:189
void drawDottedConnection(const GUIVisualizationSettings &s, const double exaggeration) const
draw dotted connections between Parent and childrens
void drawChildDottedConnections(const GUIVisualizationSettings &s, const double exaggeration) const
Draw dotted connections between parent and children.
an e3 entry point
std::vector< ConnectionGeometry > symbolsPositionAndRotation
position and rotation of every symbol over lane
bool canAutomaticSortChildren() const
return true if tag correspond to an element that can sort their children automatic ...
const PositionVector & getLaneShape() const
Definition: GNELane.cpp:115
static void setColor(const RGBColor &c)
Sets the gl-color to this value.
Definition: GLHelper.cpp:446
virtual void updateParentAdditional()
update parent after add or remove a child (can be reimplemented, for example used for statistics) ...
A point in 2D or 3D with translation and scaling methods.
Definition: Position.h:36
an e3 exit point
const std::vector< GNEAdditional * > & getChildAdditionals() const
return child additionals
const std::string & getID() const
get ID
const std::vector< GNEDemandElement * > & getChildDemandElementsByType(SumoXMLTag tag) const
return child demand elements by type
virtual double getAttributeDouble(SumoXMLAttr key) const =0
GNENet * getNet() const
get pointer to net
ChildConnections(GNEHierarchicalChildElements *hierarchicalElement)
constructor
virtual void updateParentDemandElement()
update parent after add or remove a child (can be reimplemented, for example used for statistics) ...
const std::vector< GNEEdge * > & getChildEdges() const
get child edges
GNEHierarchicalChildElements(const GNEAttributeCarrier *AC, const std::vector< GNEJunction *> &childJunctions, const std::vector< GNEEdge *> &childEdges, const std::vector< GNELane *> &childLanes, const std::vector< GNEAdditional *> &childAdditionals, const std::vector< GNEShape *> &childShapes, const std::vector< GNETAZElement *> &childTAZElements, const std::vector< GNEDemandElement *> &childDemandElements, const std::vector< GNEGenericData *> &childGenericDataElements)
Parameter Constructor.
std::map< SumoXMLTag, std::vector< GNEDemandElement *> > myDemandElementsByType
vector with the demand elements children sorted by type and filtered (to avoid duplicated ...
void addChildElement(T *element)
add child
std::vector< GNEAdditional * > myChildAdditionals
vector with the child additionas
const std::vector< GNEDemandElement * > & getChildDemandElements() const
return child demand elements
A road/street connecting two junctions (netedit-version)
Definition: GNEEdge.h:47
void drawChildConnections(const GUIVisualizationSettings &s, const GUIGlObjectType GLTypeParent, const double exaggeration) const
Draw connections between parent and children.
void sortChildAdditionals()
sort child additionals (used by Rerouters, VSS, TAZs...)
trigger: the time of the step
const std::vector< GNETAZElement * > & getChildTAZElements() const
get child TAZElements
double length() const
Returns the length.
a sink within a district (connection road)
An Element which don&#39;t belongs to GNENet but has influency in the simulation.
Definition: GNEAdditional.h:47
const std::string & getTagStr() const
get tag assigned to this object in string format
weights: time range end
const std::vector< GNEGenericData * > & getChildGenericDatas() const
return child generic data elements
bool drawForRectangleSelection
whether drawing is performed for the purpose of selecting objects using a rectangle ...
std::vector< GNEShape * > myChildShapes
vector with the child lanes
const GNETagProperties & getTagProperty() const
get Tag Property assigned to this object
std::vector< GNETAZElement * > myChildTAZElements
vector with the child TAZ Elements
double getChildRotation(const GNELane *lane)
get child rotation calculated in ChildConnections
void drawConnection(const GUIVisualizationSettings &s, const GUIGlObjectType parentType, const double exaggeration) const
draw connections between Parent and childrens
GUIVisualizationColorSettings colorSettings
color settings
static void drawDottedContourLane(const bool inspect, 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.)
GNEDemandElement * getPreviousChildDemandElement(const GNEDemandElement *demandElement) const
get previous child demand element to the given demand element
void sortChildDemandElements()
sort child demand elements
std::vector< GNEDemandElement * > myChildDemandElements
vector with the demand elements children
void removeChildElement(T *element)
remove child
const std::vector< GNELane * > & getChildLanes() const
get child lanes
Position positionAtOffset(double pos, double lateralOffset=0) const
Returns the position at the given length.
An special type of Attribute carrier that owns hierarchical elements.
virtual const std::string & getID() const =0
return ID of object
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:77
An Element which don&#39;t belongs to GNENet but has influency in the simulation.
GNEDemandElement * getNextChildDemandElement(const GNEDemandElement *demandElement) const
get next child demand element to the given demand element
std::vector< GNEEdge * > myChildEdges
vector with the child edges