Eclipse SUMO - Simulation of Urban MObility
GNEHierarchicalParentElements.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/GNENet.h>
23 #include <netedit/GNEViewNet.h>
31 #include <utils/gui/div/GLHelper.h>
33 
35 
36 // ===========================================================================
37 // member method definitions
38 // ===========================================================================
39 
40 // ---------------------------------------------------------------------------
41 // GNEHierarchicalParentElements - methods
42 // ---------------------------------------------------------------------------
43 
45  const std::vector<GNEJunction*>& parentJunctions,
46  const std::vector<GNEEdge*>& parentEdges,
47  const std::vector<GNELane*>& parentLanes,
48  const std::vector<GNEAdditional*>& parentAdditionals,
49  const std::vector<GNEShape*>& parentShapes,
50  const std::vector<GNETAZElement*>& parentTAZElements,
51  const std::vector<GNEDemandElement*>& ParentDemandElements,
52  const std::vector<GNEGenericData*>& parentGenericDatas) :
53  myParentConnections(this),
54  myParentJunctions(parentJunctions),
55  myParentEdges(parentEdges),
56  myParentLanes(parentLanes),
57  myParentAdditionals(parentAdditionals),
58  myParentShapes(parentShapes),
59  myParentTAZElements(parentTAZElements),
60  myParentDemandElements(ParentDemandElements),
61  myParentGenericDatas(parentGenericDatas),
62  myAC(AC) {
63 }
64 
65 
67 
68 
69 template <> void
71  // Check that edge is valid and doesn't exist previously
72  if (edge == nullptr) {
73  throw InvalidArgument("Trying to add an empty " + toString(SUMO_TAG_EDGE) + " parent in " + myAC->getTagStr() + " with ID='" + myAC->getID() + "'");
74  } else if (std::find(myParentEdges.begin(), myParentEdges.end(), edge) != myParentEdges.end()) {
75  throw InvalidArgument("Trying to add a duplicate " + toString(SUMO_TAG_EDGE) + " parent in " + myAC->getTagStr() + " with ID='" + myAC->getID() + "'");
76  } else {
77  myParentEdges.push_back(edge);
78  }
79 }
80 
81 
82 template <> void
84  // Check that lane is valid and doesn't exist previously
85  if (lane == nullptr) {
86  throw InvalidArgument("Trying to add an empty " + toString(SUMO_TAG_LANE) + " parent in " + myAC->getTagStr() + " with ID='" + myAC->getID() + "'");
87  } else if (std::find(myParentLanes.begin(), myParentLanes.end(), lane) != myParentLanes.end()) {
88  throw InvalidArgument("Trying to add a duplicate " + toString(SUMO_TAG_LANE) + " parent in " + myAC->getTagStr() + " with ID='" + myAC->getID() + "'");
89  } else {
90  myParentLanes.push_back(lane);
91  }
92 }
93 
94 
95 template <> void
97  // First check that additional wasn't already inserted
98  if (std::find(myParentAdditionals.begin(), myParentAdditionals.end(), additional) != myParentAdditionals.end()) {
99  throw ProcessError(additional->getTagStr() + " with ID='" + additional->getID() + "' was already inserted in " + myAC->getTagStr() + " with ID='" + myAC->getID() + "'");
100  } else {
101  myParentAdditionals.push_back(additional);
102  }
103 }
104 
105 
106 template <> void
108  // Check that shape is valid and doesn't exist previously
109  if (shape == nullptr) {
110  throw InvalidArgument("Trying to add an empty shape parent in " + myAC->getTagStr() + " with ID='" + myAC->getID() + "'");
111  } else if (std::find(myParentShapes.begin(), myParentShapes.end(), shape) != myParentShapes.end()) {
112  throw InvalidArgument("Trying to add a duplicate shape parent in " + myAC->getTagStr() + " with ID='" + myAC->getID() + "'");
113  } else {
114  myParentShapes.push_back(shape);
115  }
116 }
117 
118 
119 template <> void
121  // Check that TAZElement is valid and doesn't exist previously
122  if (TAZElement == nullptr) {
123  throw InvalidArgument("Trying to add an empty " + toString(SUMO_TAG_TAZ) + " parent in " + myAC->getTagStr() + " with ID='" + myAC->getID() + "'");
124  } else if (std::find(myParentTAZElements.begin(), myParentTAZElements.end(), TAZElement) != myParentTAZElements.end()) {
125  throw InvalidArgument("Trying to add a duplicate " + toString(SUMO_TAG_TAZ) + " parent in " + myAC->getTagStr() + " with ID='" + myAC->getID() + "'");
126  } else {
127  myParentTAZElements.push_back(TAZElement);
128  }
129 }
130 
131 
132 template <> void
134  // First check that demandElement wasn't already inserted
135  if (std::find(myParentDemandElements.begin(), myParentDemandElements.end(), demandElement) != myParentDemandElements.end()) {
136  throw ProcessError(demandElement->getTagStr() + " with ID='" + demandElement->getID() + "' was already inserted in " + myAC->getTagStr() + " with ID='" + myAC->getID() + "'");
137  } else {
138  myParentDemandElements.push_back(demandElement);
139  }
140 }
141 
142 
143 template <> void
145  // First check that GenericData wasn't already inserted
146  if (std::find(myParentGenericDatas.begin(), myParentGenericDatas.end(), genericData) != myParentGenericDatas.end()) {
147  throw ProcessError(genericData->getTagStr() + " with ID='" + genericData->getID() + "' was already inserted in " + myAC->getTagStr() + " with ID='" + myAC->getID() + "'");
148  } else {
149  myParentGenericDatas.push_back(genericData);
150  }
151 }
152 
153 
154 template <> void
156  // Check that edge is valid and exist previously
157  if (edge == nullptr) {
158  throw InvalidArgument("Trying to remove an empty " + toString(SUMO_TAG_EDGE) + " parent in " + myAC->getTagStr() + " with ID='" + myAC->getID() + "'");
159  } else {
160  auto it = std::find(myParentEdges.begin(), myParentEdges.end(), edge);
161  if (it == myParentEdges.end()) {
162  throw InvalidArgument("Trying to remove a non previously inserted " + toString(SUMO_TAG_EDGE) + " parent in " + myAC->getTagStr() + " with ID='" + myAC->getID() + "'");
163  } else {
164  myParentEdges.erase(it);
165  }
166  }
167 }
168 
169 
170 
171 template <> void
173  // Check that lane is valid and exist previously
174  if (lane == nullptr) {
175  throw InvalidArgument("Trying to remove an empty " + toString(SUMO_TAG_LANE) + " parent in " + myAC->getTagStr() + " with ID='" + myAC->getID() + "'");
176  } else if (std::find(myParentLanes.begin(), myParentLanes.end(), lane) == myParentLanes.end()) {
177  throw InvalidArgument("Trying to remove a non previously inserted " + toString(SUMO_TAG_LANE) + " parent in " + myAC->getTagStr() + " with ID='" + myAC->getID() + "'");
178  } else {
179  myParentLanes.erase(std::find(myParentLanes.begin(), myParentLanes.end(), lane));
180  }
181 }
182 
183 
184 template <> void
186  // First check that additional was already inserted
187  auto it = std::find(myParentAdditionals.begin(), myParentAdditionals.end(), additional);
188  if (it == myParentAdditionals.end()) {
189  throw ProcessError(additional->getTagStr() + " with ID='" + additional->getID() + "' doesn't exist in " + myAC->getTagStr() + " with ID='" + myAC->getID() + "'");
190  } else {
191  myParentAdditionals.erase(it);
192  }
193 }
194 
195 
196 template <> void
198  // Check that shape is valid and exist previously
199  if (shape == nullptr) {
200  throw InvalidArgument("Trying to remove an empty shape parent in " + myAC->getTagStr() + " with ID='" + myAC->getID() + "'");
201  } else if (std::find(myParentShapes.begin(), myParentShapes.end(), shape) == myParentShapes.end()) {
202  throw InvalidArgument("Trying to remove a non previously inserted shape parent in " + myAC->getTagStr() + " with ID='" + myAC->getID() + "'");
203  } else {
204  myParentShapes.erase(std::find(myParentShapes.begin(), myParentShapes.end(), shape));
205  }
206 }
207 
208 
209 template <> void
211  // Check that TAZElement is valid and exist previously
212  if (TAZElement == nullptr) {
213  throw InvalidArgument("Trying to remove an empty " + toString(SUMO_TAG_TAZ) + " parent in " + myAC->getTagStr() + " with ID='" + myAC->getID() + "'");
214  } else if (std::find(myParentTAZElements.begin(), myParentTAZElements.end(), TAZElement) == myParentTAZElements.end()) {
215  throw InvalidArgument("Trying to remove a non previously inserted " + toString(SUMO_TAG_TAZ) + " parent in " + myAC->getTagStr() + " with ID='" + myAC->getID() + "'");
216  } else {
217  myParentTAZElements.erase(std::find(myParentTAZElements.begin(), myParentTAZElements.end(), TAZElement));
218  }
219 }
220 
221 
222 template <> void
224  // First check that demandElement was already inserted
225  auto it = std::find(myParentDemandElements.begin(), myParentDemandElements.end(), demandElement);
226  if (it == myParentDemandElements.end()) {
227  throw ProcessError(demandElement->getTagStr() + " with ID='" + demandElement->getID() + "' doesn't exist in " + myAC->getTagStr() + " with ID='" + myAC->getID() + "'");
228  } else {
229  myParentDemandElements.erase(it);
230  }
231 }
232 
233 
234 template <> void
236  // First check that GenericData was already inserted
237  auto it = std::find(myParentGenericDatas.begin(), myParentGenericDatas.end(), genericData);
238  if (it == myParentGenericDatas.end()) {
239  throw ProcessError(genericData->getTagStr() + " with ID='" + genericData->getID() + "' doesn't exist in " + myAC->getTagStr() + " with ID='" + myAC->getID() + "'");
240  } else {
241  myParentGenericDatas.erase(it);
242  }
243 }
244 
245 
246 const std::vector<GNEEdge*>&
248  return myParentEdges;
249 }
250 
251 
252 const std::vector<GNELane*>&
254  return myParentLanes;
255 }
256 
257 
258 const std::vector<GNEAdditional*>&
260  return myParentAdditionals;
261 }
262 
263 
264 const std::vector<GNEShape*>&
266  return myParentShapes;
267 }
268 
269 
270 const std::vector<GNETAZElement*>&
272  return myParentTAZElements;
273 }
274 
275 
276 const std::vector<GNEDemandElement*>&
278  return myParentDemandElements;
279 }
280 
281 
282 const std::vector<GNEGenericData*>&
284  return myParentGenericDatas;
285 }
286 
287 
288 std::string
290  std::vector<std::string> solution;
291  if ((currentElement->getTagProperty().getTag() == SUMO_TAG_EDGE) && (newNextElement->getTagProperty().getTag() == SUMO_TAG_EDGE)) {
292  // reserve solution
293  solution.reserve(myParentEdges.size());
294  // iterate over edges
295  for (const auto& edge : myParentEdges) {
296  // add edge ID
297  solution.push_back(edge->getID());
298  // if current edge is the current element, then insert newNextElement ID
299  if (edge == currentElement) {
300  solution.push_back(newNextElement->getID());
301  }
302  }
303  } else if ((currentElement->getTagProperty().getTag() == SUMO_TAG_LANE) && (newNextElement->getTagProperty().getTag() == SUMO_TAG_LANE)) {
304  // reserve solution
305  solution.reserve(myParentLanes.size());
306  // iterate over lanes
307  for (const auto& lane : myParentLanes) {
308  // add lane ID
309  solution.push_back(lane->getID());
310  // if current lane is the current element, then insert newNextElement ID
311  if (lane == currentElement) {
312  solution.push_back(newNextElement->getID());
313  }
314  }
315  }
316  // remove consecutive (adjacent) duplicates
317  solution.erase(std::unique(solution.begin(), solution.end()), solution.end());
318  // return solution
319  return toString(solution);
320 }
321 
322 
325  if (myParentJunctions.size() > 0) {
326  return myParentJunctions.at(0);
327  } else {
328  throw InvalidArgument("Invalid number of parent junctions (0)");
329  }
330 }
331 
332 
335  if (myParentJunctions.size() > 1) {
336  return myParentJunctions.at(1);
337  } else {
338  throw InvalidArgument("Invalid number of parent junctions (<1)");
339  }
340 }
341 
342 
343 void
345  if (myParentJunctions.size() > 0) {
346  myParentJunctions.at(0) = junction;
347  } else {
348  throw InvalidArgument("Invalid number of parent junctions (0)");
349  }
350 }
351 
352 
353 void
355  if (myParentJunctions.size() > 1) {
356  myParentJunctions.at(1) = junction;
357  } else {
358  throw InvalidArgument("Invalid number of parent junctions (<1)");
359  }
360 }
361 
362 
363 std::vector<GNEEdge*>
365  std::vector<GNEEdge*> middleEdges;
366  // there are only middle edges if there is more than two edges
367  if (myParentEdges.size() > 2) {
368  // reserve middleEdges
369  middleEdges.reserve(myParentEdges.size() - 2);
370  // iterate over second and previous last parent edge
371  for (auto i = (myParentEdges.begin() + 1); i != (myParentEdges.end() - 1); i++) {
372  middleEdges.push_back(*i);
373  }
374  }
375  return middleEdges;
376 }
377 
378 // ---------------------------------------------------------------------------
379 // GNEHierarchicalParentElements - protected methods
380 // ---------------------------------------------------------------------------
381 
382 void
383 GNEHierarchicalParentElements::replaceParentEdges(GNEShape* elementChild, const std::string& newEdgeIDs) {
384  // remove additional of parent edges
385  for (const auto& edge : myParentEdges) {
386  edge->removeChildElement(elementChild);
387  }
388  // obtain new parent edges
389  myParentEdges = GNEAttributeCarrier::parse<std::vector<GNEEdge*> >(elementChild->getNet(), newEdgeIDs);
390  // check that lane parets aren't empty
391  if (myParentEdges.empty()) {
392  throw InvalidArgument("New list of parent edges cannot be empty");
393  } else {
394  // add additional into parent edges
395  for (const auto& edge : myParentEdges) {
396  edge->addChildElement(elementChild);
397  }
398  }
399 }
400 
401 
402 void
403 GNEHierarchicalParentElements::replaceParentEdges(GNEAdditional* elementChild, const std::string& newEdgeIDs) {
404  // remove additional of parent edges
405  for (const auto& edge : myParentEdges) {
406  edge->removeChildElement(elementChild);
407  }
408  // obtain new parent edges
409  myParentEdges = GNEAttributeCarrier::parse<std::vector<GNEEdge*> >(elementChild->getNet(), newEdgeIDs);
410  // check that lane parets aren't empty
411  if (myParentEdges.empty()) {
412  throw InvalidArgument("New list of parent edges cannot be empty");
413  } else {
414  // add additional into parent edges
415  for (const auto& edge : myParentEdges) {
416  edge->addChildElement(elementChild);
417  }
418  }
419 }
420 
421 
422 void
423 GNEHierarchicalParentElements::replaceParentEdges(GNEDemandElement* elementChild, const std::string& newEdgeIDs) {
424  // remove demandElement of parent edges
425  for (const auto& edge : myParentEdges) {
426  edge->removeChildElement(elementChild);
427  }
428  // obtain new parent edges
429  myParentEdges = GNEAttributeCarrier::parse<std::vector<GNEEdge*> >(elementChild->getNet(), newEdgeIDs);
430  // check that lane parets aren't empty
431  if (myParentEdges.empty()) {
432  throw InvalidArgument("New list of parent edges cannot be empty");
433  } else {
434  // add demandElement into parent edges
435  for (const auto& edge : myParentEdges) {
436  edge->addChildElement(elementChild);
437  }
438  }
439 }
440 
441 
442 void
443 GNEHierarchicalParentElements::replaceParentEdges(GNEDemandElement* elementChild, const std::vector<GNEEdge*>& newEdges) {
444  // remove demandElement of parent edges
445  for (const auto& edge : myParentEdges) {
446  edge->removeChildElement(elementChild);
447  }
448  // set new edges
449  myParentEdges = newEdges;
450  // check that lane parets aren't empty
451  if (myParentEdges.empty()) {
452  throw InvalidArgument("New list of parent edges cannot be empty");
453  } else {
454  // add demandElement into parent edges
455  for (const auto& edge : myParentEdges) {
456  edge->addChildElement(elementChild);
457  }
458  }
459 }
460 
461 
462 void
463 GNEHierarchicalParentElements::replaceParentEdges(GNEGenericData* elementChild, const std::vector<GNEEdge*>& newEdges) {
464  // remove genericData of parent edges
465  for (const auto& edge : myParentEdges) {
466  edge->removeChildElement(elementChild);
467  }
468  // set new edges
469  myParentEdges = newEdges;
470  // check that lane parets aren't empty
471  if (myParentEdges.empty()) {
472  throw InvalidArgument("New list of parent edges cannot be empty");
473  } else {
474  // add genericData into parent edges
475  for (const auto& edge : myParentEdges) {
476  edge->addChildElement(elementChild);
477  }
478  }
479 }
480 
481 
482 void
484  // first check that at least there is two edges
485  if (myParentEdges.size() < 1) {
486  throw InvalidArgument("Invalid minimum number of edges");
487  } else {
488  // remove demandElement of parent edges
489  myParentEdges.front()->removeChildElement(elementChild);
490  // replace first edge
491  myParentEdges[0] = newFirstEdge;
492  // add demandElement into parent edges
493  myParentEdges.front()->addChildElement(elementChild);
494  }
495 }
496 
497 
498 void
500  // first check that at least there is two edges
501  if (myParentEdges.size() < 1) {
502  throw InvalidArgument("Invalid minimum number of edges");
503  } else {
504  // remove generic data of parent edges
505  myParentEdges.front()->removeChildElement(elementChild);
506  // replace first edge
507  myParentEdges[0] = newFirstEdge;
508  // add generic data into parent edges
509  myParentEdges.front()->addChildElement(elementChild);
510  }
511 }
512 
513 
514 void
515 GNEHierarchicalParentElements::replaceMiddleParentEdges(GNEDemandElement* elementChild, const std::vector<GNEEdge*>& newMiddleEdges, const bool updateChildReferences) {
516  // declare a vector for new parent edges
517  std::vector<GNEEdge*> newEdges;
518  // check if add first edge
519  if (myParentEdges.size() > 0) {
520  newEdges.push_back(myParentEdges.front());
521  }
522  // add newMiddleEdges
523  for (const auto& edge : newMiddleEdges) {
524  newEdges.push_back(edge);
525  }
526  // check if add last edge
527  if (myParentEdges.size() > 1) {
528  newEdges.push_back(myParentEdges.back());
529  }
530  // check if we have to update references in all childs, or simply update parent edges vector
531  if (updateChildReferences) {
532  replaceParentEdges(elementChild, newEdges);
533  } else {
534  myParentEdges = newEdges;
535  }
536 }
537 
538 
539 void
541  // first check that at least there is two edges
542  if (myParentEdges.size() < 2) {
543  throw InvalidArgument("Invalid minimum number of edges");
544  } else {
545  // remove demandElement of parent edges
546  myParentEdges.back()->removeChildElement(elementChild);
547  // replace last edge
548  myParentEdges.pop_back();
549  myParentEdges.push_back(newLastEdge);
550  // add demandElement into parent edges
551  myParentEdges.back()->addChildElement(elementChild);
552  }
553 }
554 
555 
556 void
558  // first check that at least there is two edges
559  if (myParentEdges.size() < 2) {
560  throw InvalidArgument("Invalid minimum number of edges");
561  } else {
562  // remove generic data of parent edges
563  myParentEdges.back()->removeChildElement(elementChild);
564  // replace last edge
565  myParentEdges.pop_back();
566  myParentEdges.push_back(newLastEdge);
567  // add generic data into parent edges
568  myParentEdges.back()->addChildElement(elementChild);
569  }
570 }
571 
572 
573 void
574 GNEHierarchicalParentElements::replaceParentLanes(GNEAdditional* elementChild, const std::string& newLaneIDs) {
575  // remove additional of parent edges
576  for (const auto& lane : myParentLanes) {
577  lane->removeChildElement(elementChild);
578  }
579  // obtain new parent edges
580  myParentLanes = GNEAttributeCarrier::parse<std::vector<GNELane*> >(elementChild->getNet(), newLaneIDs);
581  // check that lane parets aren't empty
582  if (myParentLanes.empty()) {
583  throw InvalidArgument("New list of parent lanes cannot be empty");
584  } else {
585  // add additional into parent edges
586  for (const auto& lane : myParentLanes) {
587  lane->addChildElement(elementChild);
588  }
589  }
590 }
591 
592 
593 void
594 GNEHierarchicalParentElements::replaceParentLanes(GNEDemandElement* elementChild, const std::string& newLaneIDs) {
595  // remove demandElement of parent edges
596  for (const auto& lane : myParentLanes) {
597  lane->removeChildElement(elementChild);
598  }
599  // obtain new parent edges
600  myParentLanes = GNEAttributeCarrier::parse<std::vector<GNELane*> >(elementChild->getNet(), newLaneIDs);
601  // check that lane parets aren't empty
602  if (myParentLanes.empty()) {
603  throw InvalidArgument("New list of parent lanes cannot be empty");
604  } else {
605  // add demandElement into parent edges
606  for (const auto& lane : myParentLanes) {
607  lane->addChildElement(elementChild);
608  }
609  }
610 }
611 
612 
613 void
614 GNEHierarchicalParentElements::replaceParentLanes(GNEShape* elementChild, const std::string& newLaneIDs) {
615  // remove demandElement of parent edges
616  for (const auto& lane : myParentLanes) {
617  lane->removeChildElement(elementChild);
618  }
619  // obtain new parent edges
620  myParentLanes = GNEAttributeCarrier::parse<std::vector<GNELane*> >(elementChild->getNet(), newLaneIDs);
621  // check that lane parets aren't empty
622  if (myParentLanes.empty()) {
623  throw InvalidArgument("New list of parent lanes cannot be empty");
624  } else {
625  // add demandElement into parent edges
626  for (const auto& lane : myParentLanes) {
627  lane->addChildElement(elementChild);
628  }
629  }
630 }
631 
632 
633 void
634 GNEHierarchicalParentElements::replaceParentAdditional(GNEShape* shapeTobeChanged, const std::string& newParentAdditionalID, int additionalParentIndex) {
635  if ((int)myParentAdditionals.size() < additionalParentIndex) {
636  throw InvalidArgument(myAC->getTagStr() + " with ID '" + myAC->getID() + "' doesn't have " + toString(additionalParentIndex) + " parent additionals");
637  } else {
638  // remove additional of the children of parent additional
639  myParentAdditionals.at(additionalParentIndex)->removeChildElement(shapeTobeChanged);
640  // set new parent additional
641  myParentAdditionals.at(additionalParentIndex) = shapeTobeChanged->getNet()->retrieveAdditional(myParentAdditionals.at(additionalParentIndex)->getTagProperty().getTag(), newParentAdditionalID);
642  // add additional int the children of parent additional
643  myParentAdditionals.at(additionalParentIndex)->addChildElement(shapeTobeChanged);
644  // update geometry after inserting
645  shapeTobeChanged->updateGeometry();
646  }
647 }
648 
649 
650 void
651 GNEHierarchicalParentElements::replaceParentAdditional(GNEAdditional* additionalTobeChanged, const std::string& newParentAdditionalID, int additionalParentIndex) {
652  if ((int)myParentAdditionals.size() < additionalParentIndex) {
653  throw InvalidArgument(myAC->getTagStr() + " with ID '" + myAC->getID() + "' doesn't have " + toString(additionalParentIndex) + " parent additionals");
654  } else {
655  // remove additional of the children of parent additional
656  myParentAdditionals.at(additionalParentIndex)->removeChildElement(additionalTobeChanged);
657  // set new parent additional
658  myParentAdditionals.at(additionalParentIndex) = additionalTobeChanged->getNet()->retrieveAdditional(myParentAdditionals.at(additionalParentIndex)->getTagProperty().getTag(), newParentAdditionalID);
659  // add additional int the children of parent additional
660  myParentAdditionals.at(additionalParentIndex)->addChildElement(additionalTobeChanged);
661  // update geometry after inserting
662  additionalTobeChanged->updateGeometry();
663  }
664 }
665 
666 
667 void
668 GNEHierarchicalParentElements::replaceParentAdditional(GNEDemandElement* demandElementTobeChanged, const std::string& newParentAdditionalID, int additionalParentIndex) {
669  if ((int)myParentAdditionals.size() < additionalParentIndex) {
670  throw InvalidArgument(myAC->getTagStr() + " with ID '" + myAC->getID() + "' doesn't have " + toString(additionalParentIndex) + " parent additionals");
671  } else {
672  // remove demand element of the children of parent additional
673  myParentAdditionals.at(additionalParentIndex)->removeChildElement(demandElementTobeChanged);
674  // set new parent demand element
675  myParentAdditionals.at(additionalParentIndex) = demandElementTobeChanged->getNet()->retrieveAdditional(myParentAdditionals.at(additionalParentIndex)->getTagProperty().getTag(), newParentAdditionalID);
676  // add demand element int the children of parent additional
677  myParentAdditionals.at(additionalParentIndex)->removeChildElement(demandElementTobeChanged);
678  // update geometry after inserting
679  demandElementTobeChanged->updateGeometry();
680  }
681 }
682 
683 
684 void
686  // first check that at least there is two TAZElements
687  if (myParentTAZElements.size() < 2) {
688  throw InvalidArgument("Invalid minimum number of TAZElements");
689  } else {
690  // remove generic data of parent TAZElements
691  myParentTAZElements.front()->removeChildElement(elementChild);
692  // replace first TAZElement
693  myParentTAZElements[0] = newFirstTAZElement;
694  // add generic data into parent TAZElements
695  myParentTAZElements.front()->addChildElement(elementChild);
696  }
697 }
698 
699 
700 void
702  // first check that at least there is two TAZElements
703  if (myParentTAZElements.size() < 2) {
704  throw InvalidArgument("Invalid minimum number of TAZElements");
705  } else {
706  // remove demandElement of parent TAZElements
707  myParentTAZElements.back()->removeChildElement(elementChild);
708  // replace last TAZElement
709  myParentTAZElements.pop_back();
710  myParentTAZElements.push_back(newLastTAZElement);
711  // add demandElement into parent TAZElements
712  myParentTAZElements.back()->addChildElement(elementChild);
713  }
714 }
715 
716 
717 void
718 GNEHierarchicalParentElements::replaceParentDemandElement(GNEShape* shapeTobeChanged, const std::string& newParentDemandElementID, int demandElementParentIndex) {
719  if ((int)myParentDemandElements.size() < demandElementParentIndex) {
720  throw InvalidArgument(myAC->getTagStr() + " with ID '" + myAC->getID() + "' doesn't have " + toString(demandElementParentIndex) + " parent demand elements");
721  } else {
722  // remove demand element of the children of parent additional
723  myParentDemandElements.at(demandElementParentIndex)->removeChildElement(shapeTobeChanged);
724  // set new parent demand element
725  myParentDemandElements.at(demandElementParentIndex) = shapeTobeChanged->getNet()->retrieveDemandElement(myParentDemandElements.at(demandElementParentIndex)->getTagProperty().getTag(), newParentDemandElementID);
726  // add demand element int the children of parent additional
727  myParentDemandElements.at(demandElementParentIndex)->addChildElement(shapeTobeChanged);
728  // update geometry after inserting
729  shapeTobeChanged->updateGeometry();
730  }
731 }
732 
733 
734 void
735 GNEHierarchicalParentElements::replaceParentDemandElement(GNEAdditional* additionalTobeChanged, const std::string& newParentDemandElementID, int demandElementParentIndex) {
736  if ((int)myParentDemandElements.size() < demandElementParentIndex) {
737  throw InvalidArgument(myAC->getTagStr() + " with ID '" + myAC->getID() + "' doesn't have " + toString(demandElementParentIndex) + " parent demand elements");
738  } else {
739  // remove demand element of the children of parent additional
740  myParentDemandElements.at(demandElementParentIndex)->removeChildElement(additionalTobeChanged);
741  // set new parent demand element
742  myParentDemandElements.at(demandElementParentIndex) = additionalTobeChanged->getNet()->retrieveDemandElement(myParentDemandElements.at(demandElementParentIndex)->getTagProperty().getTag(), newParentDemandElementID);
743  // add demand element int the children of parent additional
744  myParentDemandElements.at(demandElementParentIndex)->addChildElement(additionalTobeChanged);
745  // update geometry after inserting
746  additionalTobeChanged->updateGeometry();
747  }
748 }
749 
750 
751 void
752 GNEHierarchicalParentElements::replaceParentDemandElement(GNEDemandElement* demandElementTobeChanged, const std::string& newParentDemandElementID, int demandElementParentIndex) {
753  if ((int)myParentDemandElements.size() < demandElementParentIndex) {
754  throw InvalidArgument(myAC->getTagStr() + " with ID '" + myAC->getID() + "' doesn't have " + toString(demandElementParentIndex) + " parent demand elements");
755  } else {
756  // remove additional of the children of parent additional
757  myParentDemandElements.at(demandElementParentIndex)->removeChildElement(demandElementTobeChanged);
758  // set new parent additional
759  myParentDemandElements.at(demandElementParentIndex) = demandElementTobeChanged->getNet()->retrieveDemandElement(myParentDemandElements.at(demandElementParentIndex)->getTagProperty().getTag(), newParentDemandElementID);
760  // add additional int the children of parent additional
761  myParentDemandElements.at(demandElementParentIndex)->addChildElement(demandElementTobeChanged);
762  // update geometry after inserting
763  demandElementTobeChanged->updateGeometry();
764  }
765 }
766 
767 
768 /****************************************************************************/
const std::string & getID() const
get ID
std::vector< GNEJunction * > myParentJunctions
vector of junction parents
void replaceFirstParentTAZElement(GNEGenericData *elementChild, GNETAZElement *newFirstTAZElement)
replace the first parent TAZElement (used by generic data elements)
std::vector< GNEAdditional * > myParentAdditionals
vector of additional parents
void replaceLastParentTAZElement(GNEGenericData *elementChild, GNETAZElement *newLastTAZElement)
replace the last parent TAZElement (used by demand elements)
begin/end of the description of a single lane
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
std::string getNewListOfParents(const GNENetworkElement *currentElement, const GNENetworkElement *newNextElement) const
if use edge/parent lanes as a list of consecutive elements, obtain a list of IDs of elements after in...
a traffic assignment zone
std::vector< GNEEdge * > myParentEdges
vector of edge parents
void updateSecondParentJunction(GNEJunction *junction)
update last parent junction
const std::vector< GNELane * > & getParentLanes() const
get parent lanes
std::vector< GNEGenericData * > myParentGenericDatas
vector of generic datas parents
GNEJunction * getSecondParentJunction() const
remove parent junction
virtual void updateGeometry()=0
update pre-computed geometry information
void updateFirstParentJunction(GNEJunction *junction)
update front parent junction
An Element which don&#39;t belongs to GNENet but has influency in the simulation.
Definition: GNETAZElement.h:46
std::vector< GNELane * > myParentLanes
vector of lane parents
const std::string & getID() const
get ID
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
const std::vector< GNEEdge * > & getParentEdges() const
get parent edges
GNEJunction * getFirstParentJunction() const
get front parent junction
const std::vector< GNEAdditional * > & getParentAdditionals() const
get parent additionals
std::vector< GNEDemandElement * > myParentDemandElements
vector of demand elements parents
GNEAdditional * retrieveAdditional(SumoXMLTag type, const std::string &id, bool hardFail=true) const
Returns the named additional.
Definition: GNENet.cpp:2216
std::vector< GNEEdge * > getMiddleParentEdges() const
get middle (via) parent edges
const GNEAttributeCarrier * myAC
pointer to AC (needed to avoid diamond problem)
std::string toString(const T &t, std::streamsize accuracy=gPrecision)
Definition: ToString.h:44
GNEDemandElement * retrieveDemandElement(SumoXMLTag type, const std::string &id, bool hardFail=true) const
Returns the named demand element.
Definition: GNENet.cpp:2337
const std::string & getID() const
get ID
void replaceMiddleParentEdges(GNEDemandElement *elementChild, const std::vector< GNEEdge *> &newMiddleEdges, const bool updateChildReferences)
replace middle (via) parent edges
virtual void updateGeometry()=0
update pre-computed geometry information
GNENet * getNet() const
get pointer to net
void replaceParentAdditional(GNEShape *shapeTobeChanged, const std::string &newParentAdditionalID, int additionalParentIndex)
replace the parent additional of a shape
const std::vector< GNEDemandElement * > & getParentDemandElements() const
get parent demand elements
std::vector< GNEShape * > myParentShapes
vector of shape parents
GNEHierarchicalParentElements(const GNEAttributeCarrier *AC, const std::vector< GNEJunction *> &parentJunctions, const std::vector< GNEEdge *> &parentEdges, const std::vector< GNELane *> &parentLanes, const std::vector< GNEAdditional *> &parentAdditionals, const std::vector< GNEShape *> &parentShapes, const std::vector< GNETAZElement *> &parentTAZElements, const std::vector< GNEDemandElement *> &parentDemandElements, const std::vector< GNEGenericData *> &parentGenericDatas)
Constructor used by elements that have another additionals as parent.
begin/end of the description of an edge
void addParentElement(T *element)
add child
A road/street connecting two junctions (netedit-version)
Definition: GNEEdge.h:47
void replaceParentLanes(GNEShape *elementChild, const std::string &newLaneIDs)
replace the parent edges of a shape
const std::vector< GNEShape * > & getParentShapes() const
get parent shapes
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
const GNETagProperties & getTagProperty() const
get Tag Property assigned to this object
std::vector< GNETAZElement * > myParentTAZElements
vector of TAZElement parents
virtual void updateGeometry()=0
update pre-computed geometry information
void removeParentElement(T *element)
remove child
void replaceFirstParentEdge(GNEDemandElement *elementChild, GNEEdge *newFirstEdge)
replace the first parent edge (used by demand elements)
void replaceLastParentEdge(GNEDemandElement *elementChild, GNEEdge *newLastEdge)
replace the last parent edge (used by demand elements)
const std::vector< GNEGenericData * > & getParentGenericDatas() const
get parent demand elements
void replaceParentDemandElement(GNEShape *shapeTobeChanged, const std::string &newParentDemandElementID, int demandElementParentIndex)
replace the parent demand element of a shape
virtual const std::string & getID() const =0
return ID of object
An Element which don&#39;t belongs to GNENet but has influency in the simulation.
void replaceParentEdges(GNEShape *elementChild, const std::string &newEdgeIDs)
replace the parent edges of a shape
const std::vector< GNETAZElement * > & getParentTAZElements() const
get parent TAZElements