1 /****************************************************************************/
2 // Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.org/sumo
3 // Copyright (C) 2001-2019 German Aerospace Center (DLR) and others.
4 // This program and the accompanying materials
5 // are made available under the terms of the Eclipse Public License v2.0
6 // which accompanies this distribution, and is available at
7 // http://www.eclipse.org/legal/epl-v20.html
8 // SPDX-License-Identifier: EPL-2.0
9 /****************************************************************************/
10 /// @file GNEHierarchicalElementParents.cpp
11 /// @author Pablo Alvarez Lopez
12 /// @date Dec 2015
13 /// @version $Id$
14 ///
15 // A abstract class for representation of additional elements
16 /****************************************************************************/
17
18 // ===========================================================================
19 // included modules
20 // ===========================================================================
21 #include <config.h>
22
23 #include <netedit/GNENet.h>
24 #include <netedit/GNEViewNet.h>
25 #include <netedit/GNEViewParent.h>
26 #include <netedit/additionals/GNEAdditional.h>
27 #include <netedit/additionals/GNEShape.h>
28 #include <netedit/demandelements/GNEDemandElement.h>
29 #include <netedit/frames/GNESelectorFrame.h>
30 #include <netedit/netelements/GNEEdge.h>
31 #include <netedit/netelements/GNEJunction.h>
32 #include <netedit/netelements/GNELane.h>
33 #include <utils/common/StringTokenizer.h>
34 #include <utils/gui/div/GLHelper.h>
35 #include <utils/gui/div/GUIGlobalSelection.h>
36 #include <utils/gui/div/GUIParameterTableWindow.h>
37 #include <utils/gui/globjects/GLIncludes.h>
38 #include <utils/gui/globjects/GUIGLObjectPopupMenu.h>
39 #include <utils/gui/images/GUITextureSubSys.h>
40 #include <utils/options/OptionsCont.h>
41
42 #include "GNEHierarchicalElementParents.h"
43
44 // ===========================================================================
45 // member method definitions
46 // ===========================================================================
47
GNEHierarchicalElementParents(GNEAttributeCarrier * AC,const std::vector<GNEEdge * > & edgeParents,const std::vector<GNELane * > & laneParents,const std::vector<GNEShape * > & shapeParents,const std::vector<GNEAdditional * > & additionalParents,const std::vector<GNEDemandElement * > & demandElementParents)48 GNEHierarchicalElementParents::GNEHierarchicalElementParents(GNEAttributeCarrier* AC,
49 const std::vector<GNEEdge*>& edgeParents,
50 const std::vector<GNELane*>& laneParents,
51 const std::vector<GNEShape*>& shapeParents,
52 const std::vector<GNEAdditional*>& additionalParents,
53 const std::vector<GNEDemandElement*>& demandElementParents) :
54 myParentConnections(this),
55 myEdgeParents(edgeParents),
56 myLaneParents(laneParents),
57 myShapeParents(shapeParents),
58 myAdditionalParents(additionalParents),
59 myDemandElementParents(demandElementParents),
60 myAC(AC) {
61 }
62
63
~GNEHierarchicalElementParents()64 GNEHierarchicalElementParents::~GNEHierarchicalElementParents() {}
65
66
67 void
addAdditionalParent(GNEAdditional * additional)68 GNEHierarchicalElementParents::addAdditionalParent(GNEAdditional* additional) {
69 // First check that additional wasn't already inserted
70 if (std::find(myAdditionalParents.begin(), myAdditionalParents.end(), additional) != myAdditionalParents.end()) {
71 throw ProcessError(additional->getTagStr() + " with ID='" + additional->getID() + "' was already inserted in " + myAC->getTagStr() + " with ID='" + myAC->getID() + "'");
72 } else {
73 myAdditionalParents.push_back(additional);
74 // only execute post operations if update geometry is enabled
75 if (additional->getViewNet()->getNet()->isUpdateGeometryEnabled()) {
76 updateGeometry(true);
77 }
78 }
79 }
80
81
82 void
removeAdditionalParent(GNEAdditional * additional)83 GNEHierarchicalElementParents::removeAdditionalParent(GNEAdditional* additional) {
84 // First check that additional was already inserted
85 auto it = std::find(myAdditionalParents.begin(), myAdditionalParents.end(), additional);
86 if (it == myAdditionalParents.end()) {
87 throw ProcessError(additional->getTagStr() + " with ID='" + additional->getID() + "' doesn't exist in " + myAC->getTagStr() + " with ID='" + myAC->getID() + "'");
88 } else {
89 myAdditionalParents.erase(it);
90 // only execute post operations if update geometry is enabled
91 if (additional->getViewNet()->getNet()->isUpdateGeometryEnabled()) {
92 updateGeometry(true);
93 }
94 }
95 }
96
97
98 const std::vector<GNEAdditional*>&
getAdditionalParents() const99 GNEHierarchicalElementParents::getAdditionalParents() const {
100 return myAdditionalParents;
101 }
102
103
104 void
addDemandElementParent(GNEDemandElement * demandElement)105 GNEHierarchicalElementParents::addDemandElementParent(GNEDemandElement* demandElement) {
106 // First check that demandElement wasn't already inserted
107 if (std::find(myDemandElementParents.begin(), myDemandElementParents.end(), demandElement) != myDemandElementParents.end()) {
108 throw ProcessError(demandElement->getTagStr() + " with ID='" + demandElement->getID() + "' was already inserted in " + myAC->getTagStr() + " with ID='" + myAC->getID() + "'");
109 } else {
110 myDemandElementParents.push_back(demandElement);
111 // update geometry (for set geometry of lines between Parents and Parents)
112 if (demandElement->getViewNet()->getNet()->isUpdateGeometryEnabled()) {
113 updateGeometry(true);
114 }
115 }
116 }
117
118
119 void
removeDemandElementParent(GNEDemandElement * demandElement)120 GNEHierarchicalElementParents::removeDemandElementParent(GNEDemandElement* demandElement) {
121 // First check that demandElement was already inserted
122 auto it = std::find(myDemandElementParents.begin(), myDemandElementParents.end(), demandElement);
123 if (it == myDemandElementParents.end()) {
124 throw ProcessError(demandElement->getTagStr() + " with ID='" + demandElement->getID() + "' doesn't exist in " + myAC->getTagStr() + " with ID='" + myAC->getID() + "'");
125 } else {
126 myDemandElementParents.erase(it);
127 // update geometry (for remove geometry of lines between Parents and Parents)
128 if (demandElement->getViewNet()->getNet()->isUpdateGeometryEnabled()) {
129 updateGeometry(true);
130 }
131 }
132 }
133
134
135 const std::vector<GNEDemandElement*>&
getDemandElementParents() const136 GNEHierarchicalElementParents::getDemandElementParents() const {
137 return myDemandElementParents;
138 }
139
140
141 void
addEdgeParent(GNEEdge * edge)142 GNEHierarchicalElementParents::addEdgeParent(GNEEdge* edge) {
143 // Check that edge is valid and doesn't exist previously
144 if (edge == nullptr) {
145 throw InvalidArgument("Trying to add an empty " + toString(SUMO_TAG_EDGE) + " parent in " + myAC->getTagStr() + " with ID='" + myAC->getID() + "'");
146 } else if (std::find(myEdgeParents.begin(), myEdgeParents.end(), edge) != myEdgeParents.end()) {
147 throw InvalidArgument("Trying to add a duplicate " + toString(SUMO_TAG_EDGE) + " parent in " + myAC->getTagStr() + " with ID='" + myAC->getID() + "'");
148 } else {
149 myEdgeParents.push_back(edge);
150 }
151 }
152
153
154 void
removeEdgeParent(GNEEdge * edge)155 GNEHierarchicalElementParents::removeEdgeParent(GNEEdge* edge) {
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 if (std::find(myEdgeParents.begin(), myEdgeParents.end(), edge) == myEdgeParents.end()) {
160 throw InvalidArgument("Trying to remove a non previously inserted " + toString(SUMO_TAG_EDGE) + " parent in " + myAC->getTagStr() + " with ID='" + myAC->getID() + "'");
161 } else {
162 myEdgeParents.erase(std::find(myEdgeParents.begin(), myEdgeParents.end(), edge));
163 }
164 }
165
166
167 const std::vector<GNEEdge*>&
getEdgeParents() const168 GNEHierarchicalElementParents::getEdgeParents() const {
169 return myEdgeParents;
170 }
171
172
173 void
addLaneParent(GNELane * lane)174 GNEHierarchicalElementParents::addLaneParent(GNELane* lane) {
175 // Check that lane is valid and doesn't exist previously
176 if (lane == nullptr) {
177 throw InvalidArgument("Trying to add an empty " + toString(SUMO_TAG_EDGE) + " parent in " + myAC->getTagStr() + " with ID='" + myAC->getID() + "'");
178 } else if (std::find(myLaneParents.begin(), myLaneParents.end(), lane) != myLaneParents.end()) {
179 throw InvalidArgument("Trying to add a duplicate " + toString(SUMO_TAG_EDGE) + " parent in " + myAC->getTagStr() + " with ID='" + myAC->getID() + "'");
180 } else {
181 myLaneParents.push_back(lane);
182 }
183 }
184
185
186 void
removeLaneParent(GNELane * lane)187 GNEHierarchicalElementParents::removeLaneParent(GNELane* lane) {
188 // Check that lane is valid and exist previously
189 if (lane == nullptr) {
190 throw InvalidArgument("Trying to remove an empty " + toString(SUMO_TAG_EDGE) + " parent in " + myAC->getTagStr() + " with ID='" + myAC->getID() + "'");
191 } else if (std::find(myLaneParents.begin(), myLaneParents.end(), lane) == myLaneParents.end()) {
192 throw InvalidArgument("Trying to remove a non previously inserted " + toString(SUMO_TAG_EDGE) + " parent in " + myAC->getTagStr() + " with ID='" + myAC->getID() + "'");
193 } else {
194 myLaneParents.erase(std::find(myLaneParents.begin(), myLaneParents.end(), lane));
195 }
196 }
197
198
199 const std::vector<GNELane*>&
getLaneParents() const200 GNEHierarchicalElementParents::getLaneParents() const {
201 return myLaneParents;
202 }
203
204
205 void
addShapeParent(GNEShape * shape)206 GNEHierarchicalElementParents::addShapeParent(GNEShape* shape) {
207 // Check that shape is valid and doesn't exist previously
208 if (shape == nullptr) {
209 throw InvalidArgument("Trying to add an empty " + toString(SUMO_TAG_EDGE) + " parent in " + myAC->getTagStr() + " with ID='" + myAC->getID() + "'");
210 } else if (std::find(myShapeParents.begin(), myShapeParents.end(), shape) != myShapeParents.end()) {
211 throw InvalidArgument("Trying to add a duplicate " + toString(SUMO_TAG_EDGE) + " parent in " + myAC->getTagStr() + " with ID='" + myAC->getID() + "'");
212 } else {
213 myShapeParents.push_back(shape);
214 }
215 }
216
217
218 void
removeShapeParent(GNEShape * shape)219 GNEHierarchicalElementParents::removeShapeParent(GNEShape* shape) {
220 // Check that shape is valid and exist previously
221 if (shape == nullptr) {
222 throw InvalidArgument("Trying to remove an empty " + toString(SUMO_TAG_EDGE) + " parent in " + myAC->getTagStr() + " with ID='" + myAC->getID() + "'");
223 } else if (std::find(myShapeParents.begin(), myShapeParents.end(), shape) == myShapeParents.end()) {
224 throw InvalidArgument("Trying to remove a non previously inserted " + toString(SUMO_TAG_EDGE) + " parent in " + myAC->getTagStr() + " with ID='" + myAC->getID() + "'");
225 } else {
226 myShapeParents.erase(std::find(myShapeParents.begin(), myShapeParents.end(), shape));
227 }
228 }
229
230
231 const std::vector<GNEShape*>&
getShapeParents() const232 GNEHierarchicalElementParents::getShapeParents() const {
233 return myShapeParents;
234 }
235
236 // ---------------------------------------------------------------------------
237 // GNEHierarchicalElementParents::ParentConnections - methods
238 // ---------------------------------------------------------------------------
239
ParentConnections(GNEHierarchicalElementParents * hierarchicalElement)240 GNEHierarchicalElementParents::ParentConnections::ParentConnections(GNEHierarchicalElementParents* hierarchicalElement) :
241 myHierarchicalElement(hierarchicalElement) {}
242
243
244 void
update()245 GNEHierarchicalElementParents::ParentConnections::update() {
246 // first clear connection positions
247 connectionPositions.clear();
248 symbolsPositionAndRotation.clear();
249
250 // calculate position and rotation of every simbol for every edge
251 for (auto i : myHierarchicalElement->myEdgeParents) {
252 for (auto j : i->getLanes()) {
253 std::pair<Position, double> posRot;
254 // set position and lenght depending of shape's lengt
255 if (j->getShape().length() - 6 > 0) {
256 posRot.first = j->getShape().positionAtOffset(j->getShape().length() - 6);
257 posRot.second = j->getShape().rotationDegreeAtOffset(j->getShape().length() - 6);
258 } else {
259 posRot.first = j->getShape().positionAtOffset(j->getShape().length());
260 posRot.second = j->getShape().rotationDegreeAtOffset(j->getShape().length());
261 }
262 symbolsPositionAndRotation.push_back(posRot);
263 }
264 }
265
266 // calculate position and rotation of every symbol for every lane
267 for (auto i : myHierarchicalElement->myLaneParents) {
268 std::pair<Position, double> posRot;
269 // set position and lenght depending of shape's lengt
270 if (i->getShape().length() - 6 > 0) {
271 posRot.first = i->getShape().positionAtOffset(i->getShape().length() - 6);
272 posRot.second = i->getShape().rotationDegreeAtOffset(i->getShape().length() - 6);
273 } else {
274 posRot.first = i->getShape().positionAtOffset(i->getShape().length());
275 posRot.second = i->getShape().rotationDegreeAtOffset(i->getShape().length());
276 }
277 symbolsPositionAndRotation.push_back(posRot);
278 }
279
280 // calculate position for every additional parent
281 for (auto i : myHierarchicalElement->myAdditionalParents) {
282 // check that position is different of position
283 if (i->getPositionInView() != myHierarchicalElement->getPositionInView()) {
284 std::vector<Position> posConnection;
285 double A = std::abs(i->getPositionInView().x() - myHierarchicalElement->getPositionInView().x());
286 double B = std::abs(i->getPositionInView().y() - myHierarchicalElement->getPositionInView().y());
287 // Set positions of connection's vertex. Connection is build from Entry to E3
288 posConnection.push_back(i->getPositionInView());
289 if (myHierarchicalElement->getPositionInView().x() > i->getPositionInView().x()) {
290 if (myHierarchicalElement->getPositionInView().y() > i->getPositionInView().y()) {
291 posConnection.push_back(Position(i->getPositionInView().x() + A, i->getPositionInView().y()));
292 } else {
293 posConnection.push_back(Position(i->getPositionInView().x(), i->getPositionInView().y() - B));
294 }
295 } else {
296 if (myHierarchicalElement->getPositionInView().y() > i->getPositionInView().y()) {
297 posConnection.push_back(Position(i->getPositionInView().x(), i->getPositionInView().y() + B));
298 } else {
299 posConnection.push_back(Position(i->getPositionInView().x() - A, i->getPositionInView().y()));
300 }
301 }
302 posConnection.push_back(myHierarchicalElement->getPositionInView());
303 connectionPositions.push_back(posConnection);
304 }
305 }
306
307 // calculate geometry for connections between parent and parents
308 for (auto i : symbolsPositionAndRotation) {
309 std::vector<Position> posConnection;
310 double A = std::abs(i.first.x() - myHierarchicalElement->getPositionInView().x());
311 double B = std::abs(i.first.y() - myHierarchicalElement->getPositionInView().y());
312 // Set positions of connection's vertex. Connection is build from Entry to E3
313 posConnection.push_back(i.first);
314 if (myHierarchicalElement->getPositionInView().x() > i.first.x()) {
315 if (myHierarchicalElement->getPositionInView().y() > i.first.y()) {
316 posConnection.push_back(Position(i.first.x() + A, i.first.y()));
317 } else {
318 posConnection.push_back(Position(i.first.x(), i.first.y() - B));
319 }
320 } else {
321 if (myHierarchicalElement->getPositionInView().y() > i.first.y()) {
322 posConnection.push_back(Position(i.first.x(), i.first.y() + B));
323 } else {
324 posConnection.push_back(Position(i.first.x() - A, i.first.y()));
325 }
326 }
327 posConnection.push_back(myHierarchicalElement->getPositionInView());
328 connectionPositions.push_back(posConnection);
329 }
330
331 }
332
333
334 void
draw(GUIGlObjectType parentType) const335 GNEHierarchicalElementParents::ParentConnections::draw(GUIGlObjectType parentType) const {
336 // Iterate over myConnectionPositions
337 for (auto i : connectionPositions) {
338 // Add a draw matrix
339 glPushMatrix();
340 // traslate in the Z axis
341 glTranslated(0, 0, parentType - 0.01);
342 // Set color of the base
343 GLHelper::setColor(RGBColor(255, 235, 0));
344 for (auto j = i.begin(); (j + 1) != i.end(); j++) {
345 // Draw Lines
346 GLHelper::drawLine((*j), (*(j + 1)));
347 }
348 // Pop draw matrix
349 glPopMatrix();
350 }
351 }
352
353 // ---------------------------------------------------------------------------
354 // GNEHierarchicalElementParents - protected methods
355 // ---------------------------------------------------------------------------
356
357
358 void
changeEdgeParents(GNEShape * elementChild,const std::string & newEdgeIDs)359 GNEHierarchicalElementParents::changeEdgeParents(GNEShape* elementChild, const std::string& newEdgeIDs) {
360 // remove additional of edge parents
361 for (const auto& i : myEdgeParents) {
362 i->removeShapeChild(elementChild);
363 }
364 // obtain new parent edges
365 myEdgeParents = GNEAttributeCarrier::parse<std::vector<GNEEdge*> >(elementChild->getNet(), newEdgeIDs);
366 // check that lane parets aren't empty
367 if (myEdgeParents.empty()) {
368 throw InvalidArgument("New list of edge parents cannot be empty");
369 } else {
370 // add additional into edge parents
371 for (const auto& i : myEdgeParents) {
372 i->addShapeChild(elementChild);
373 }
374 }
375 }
376
377
378 void
changeEdgeParents(GNEAdditional * elementChild,const std::string & newEdgeIDs)379 GNEHierarchicalElementParents::changeEdgeParents(GNEAdditional* elementChild, const std::string& newEdgeIDs) {
380 // remove additional of edge parents
381 for (const auto& i : myEdgeParents) {
382 i->removeAdditionalChild(elementChild);
383 }
384 // obtain new parent edges
385 myEdgeParents = GNEAttributeCarrier::parse<std::vector<GNEEdge*> >(elementChild->getViewNet()->getNet(), newEdgeIDs);
386 // check that lane parets aren't empty
387 if (myEdgeParents.empty()) {
388 throw InvalidArgument("New list of edge parents cannot be empty");
389 } else {
390 // add additional into edge parents
391 for (const auto& i : myEdgeParents) {
392 i->addAdditionalChild(elementChild);
393 }
394 }
395 }
396
397
398 void
changeEdgeParents(GNEDemandElement * elementChild,const std::string & newEdgeIDs)399 GNEHierarchicalElementParents::changeEdgeParents(GNEDemandElement* elementChild, const std::string& newEdgeIDs) {
400 // remove demandElement of edge parents
401 for (const auto& i : myEdgeParents) {
402 i->removeDemandElementChild(elementChild);
403 }
404 // obtain new parent edges
405 myEdgeParents = GNEAttributeCarrier::parse<std::vector<GNEEdge*> >(elementChild->getViewNet()->getNet(), newEdgeIDs);
406 // check that lane parets aren't empty
407 if (myEdgeParents.empty()) {
408 throw InvalidArgument("New list of edge parents cannot be empty");
409 } else {
410 // add demandElement into edge parents
411 for (const auto& i : myEdgeParents) {
412 i->addDemandElementChild(elementChild);
413 }
414 }
415 }
416
417
418 void
changeLaneParents(GNEAdditional * elementChild,const std::string & newLaneIDs)419 GNEHierarchicalElementParents::changeLaneParents(GNEAdditional* elementChild, const std::string& newLaneIDs) {
420 // remove additional of edge parents
421 for (const auto& i : myLaneParents) {
422 i->removeAdditionalChild(elementChild);
423 }
424 // obtain new parent edges
425 myLaneParents = GNEAttributeCarrier::parse<std::vector<GNELane*> >(elementChild->getViewNet()->getNet(), newLaneIDs);
426 // check that lane parets aren't empty
427 if (myLaneParents.empty()) {
428 throw InvalidArgument("New list of lane parents cannot be empty");
429 } else {
430 // add additional into edge parents
431 for (const auto& i : myLaneParents) {
432 i->addAdditionalChild(elementChild);
433 }
434 }
435 }
436
437
438 void
changeLaneParents(GNEDemandElement * elementChild,const std::string & newLaneIDs)439 GNEHierarchicalElementParents::changeLaneParents(GNEDemandElement* elementChild, const std::string& newLaneIDs) {
440 // remove demandElement of edge parents
441 for (const auto& i : myLaneParents) {
442 i->removeDemandElementChild(elementChild);
443 }
444 // obtain new parent edges
445 myLaneParents = GNEAttributeCarrier::parse<std::vector<GNELane*> >(elementChild->getViewNet()->getNet(), newLaneIDs);
446 // check that lane parets aren't empty
447 if (myLaneParents.empty()) {
448 throw InvalidArgument("New list of lane parents cannot be empty");
449 } else {
450 // add demandElement into edge parents
451 for (const auto& i : myLaneParents) {
452 i->addDemandElementChild(elementChild);
453 }
454 }
455 }
456
457
458 void
changeLaneParents(GNEShape * elementChild,const std::string & newLaneIDs)459 GNEHierarchicalElementParents::changeLaneParents(GNEShape* elementChild, const std::string& newLaneIDs) {
460 // remove demandElement of edge parents
461 for (const auto& i : myLaneParents) {
462 i->removeShapeChild(elementChild);
463 }
464 // obtain new parent edges
465 myLaneParents = GNEAttributeCarrier::parse<std::vector<GNELane*> >(elementChild->getNet(), newLaneIDs);
466 // check that lane parets aren't empty
467 if (myLaneParents.empty()) {
468 throw InvalidArgument("New list of lane parents cannot be empty");
469 } else {
470 // add demandElement into edge parents
471 for (const auto& i : myLaneParents) {
472 i->addShapeChild(elementChild);
473 }
474 }
475 }
476
477
478 void
changeAdditionalParent(GNEShape * shapeTobeChanged,const std::string & newAdditionalParentID,int additionalParentIndex)479 GNEHierarchicalElementParents::changeAdditionalParent(GNEShape* shapeTobeChanged, const std::string& newAdditionalParentID, int additionalParentIndex) {
480 if ((int)myAdditionalParents.size() < additionalParentIndex) {
481 throw InvalidArgument(myAC->getTagStr() + " with ID '" + myAC->getID() + "' doesn't have " + toString(additionalParentIndex) + " additional parents");
482 } else {
483 // remove additional of the childs of parent additional
484 myAdditionalParents.at(additionalParentIndex)->removeShapeChild(shapeTobeChanged);
485 // set new additional parent
486 myAdditionalParents.at(additionalParentIndex) = shapeTobeChanged->getNet()->retrieveAdditional(myAdditionalParents.at(additionalParentIndex)->getTagProperty().getTag(), newAdditionalParentID);
487 // add additional int the childs of parent additional
488 myAdditionalParents.at(additionalParentIndex)->addShapeChild(shapeTobeChanged);
489 // update geometry after inserting
490 updateGeometry(true);
491 }
492 }
493
494
495 void
changeAdditionalParent(GNEAdditional * additionalTobeChanged,const std::string & newAdditionalParentID,int additionalParentIndex)496 GNEHierarchicalElementParents::changeAdditionalParent(GNEAdditional* additionalTobeChanged, const std::string& newAdditionalParentID, int additionalParentIndex) {
497 if ((int)myAdditionalParents.size() < additionalParentIndex) {
498 throw InvalidArgument(myAC->getTagStr() + " with ID '" + myAC->getID() + "' doesn't have " + toString(additionalParentIndex) + " additional parents");
499 } else {
500 // remove additional of the childs of parent additional
501 myAdditionalParents.at(additionalParentIndex)->removeAdditionalChild(additionalTobeChanged);
502 // set new additional parent
503 myAdditionalParents.at(additionalParentIndex) = additionalTobeChanged->getViewNet()->getNet()->retrieveAdditional(myAdditionalParents.at(additionalParentIndex)->getTagProperty().getTag(), newAdditionalParentID);
504 // add additional int the childs of parent additional
505 myAdditionalParents.at(additionalParentIndex)->addAdditionalChild(additionalTobeChanged);
506 // update geometry after inserting
507 updateGeometry(true);
508 }
509 }
510
511
512 void
changeAdditionalParent(GNEDemandElement * demandElementTobeChanged,const std::string & newAdditionalParentID,int additionalParentIndex)513 GNEHierarchicalElementParents::changeAdditionalParent(GNEDemandElement* demandElementTobeChanged, const std::string& newAdditionalParentID, int additionalParentIndex) {
514 if ((int)myAdditionalParents.size() < additionalParentIndex) {
515 throw InvalidArgument(myAC->getTagStr() + " with ID '" + myAC->getID() + "' doesn't have " + toString(additionalParentIndex) + " additional parents");
516 } else {
517 // remove demand element of the childs of parent additional
518 myAdditionalParents.at(additionalParentIndex)->removeDemandElementChild(demandElementTobeChanged);
519 // set new demand element parent
520 myAdditionalParents.at(additionalParentIndex) = demandElementTobeChanged->getViewNet()->getNet()->retrieveAdditional(myAdditionalParents.at(additionalParentIndex)->getTagProperty().getTag(), newAdditionalParentID);
521 // add demand element int the childs of parent additional
522 myAdditionalParents.at(additionalParentIndex)->removeDemandElementChild(demandElementTobeChanged);
523 // update geometry after inserting
524 updateGeometry(true);
525 }
526 }
527
528
529 void
changeDemandElementParent(GNEShape * shapeTobeChanged,const std::string & newDemandElementParentID,int demandElementParentIndex)530 GNEHierarchicalElementParents::changeDemandElementParent(GNEShape* shapeTobeChanged, const std::string& newDemandElementParentID, int demandElementParentIndex) {
531 if ((int)myDemandElementParents.size() < demandElementParentIndex) {
532 throw InvalidArgument(myAC->getTagStr() + " with ID '" + myAC->getID() + "' doesn't have " + toString(demandElementParentIndex) + " demand element parents");
533 } else {
534 // remove demand element of the childs of parent additional
535 myDemandElementParents.at(demandElementParentIndex)->removeShapeChild(shapeTobeChanged);
536 // set new demand element parent
537 myDemandElementParents.at(demandElementParentIndex) = shapeTobeChanged->getNet()->retrieveDemandElement(myDemandElementParents.at(demandElementParentIndex)->getTagProperty().getTag(), newDemandElementParentID);
538 // add demand element int the childs of parent additional
539 myDemandElementParents.at(demandElementParentIndex)->addShapeChild(shapeTobeChanged);
540 // update geometry after inserting
541 updateGeometry(true);
542 }
543 }
544
545
546 void
changeDemandElementParent(GNEAdditional * additionalTobeChanged,const std::string & newDemandElementParentID,int demandElementParentIndex)547 GNEHierarchicalElementParents::changeDemandElementParent(GNEAdditional* additionalTobeChanged, const std::string& newDemandElementParentID, int demandElementParentIndex) {
548 if ((int)myDemandElementParents.size() < demandElementParentIndex) {
549 throw InvalidArgument(myAC->getTagStr() + " with ID '" + myAC->getID() + "' doesn't have " + toString(demandElementParentIndex) + " demand element parents");
550 } else {
551 // remove demand element of the childs of parent additional
552 myDemandElementParents.at(demandElementParentIndex)->removeAdditionalChild(additionalTobeChanged);
553 // set new demand element parent
554 myDemandElementParents.at(demandElementParentIndex) = additionalTobeChanged->getViewNet()->getNet()->retrieveDemandElement(myDemandElementParents.at(demandElementParentIndex)->getTagProperty().getTag(), newDemandElementParentID);
555 // add demand element int the childs of parent additional
556 myDemandElementParents.at(demandElementParentIndex)->addAdditionalChild(additionalTobeChanged);
557 // update geometry after inserting
558 updateGeometry(true);
559 }
560 }
561
562
563 void
changeDemandElementParent(GNEDemandElement * demandElementTobeChanged,const std::string & newDemandElementParentID,int demandElementParentIndex)564 GNEHierarchicalElementParents::changeDemandElementParent(GNEDemandElement* demandElementTobeChanged, const std::string& newDemandElementParentID, int demandElementParentIndex) {
565 if ((int)myDemandElementParents.size() < demandElementParentIndex) {
566 throw InvalidArgument(myAC->getTagStr() + " with ID '" + myAC->getID() + "' doesn't have " + toString(demandElementParentIndex) + " demand element parents");
567 } else {
568 // remove additional of the childs of parent additional
569 myDemandElementParents.at(demandElementParentIndex)->removeDemandElementChild(demandElementTobeChanged);
570 // set new additional parent
571 myDemandElementParents.at(demandElementParentIndex) = demandElementTobeChanged->getViewNet()->getNet()->retrieveDemandElement(myDemandElementParents.at(demandElementParentIndex)->getTagProperty().getTag(), newDemandElementParentID);
572 // add additional int the childs of parent additional
573 myDemandElementParents.at(demandElementParentIndex)->addDemandElementChild(demandElementTobeChanged);
574 // update geometry after inserting
575 updateGeometry(true);
576 }
577 }
578
579 /****************************************************************************/
580