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    GNEChange_Edge.cpp
11 /// @author  Jakob Erdmann
12 /// @date    Mar 2011
13 /// @version $Id$
14 ///
15 // A network change in which a single junction is created or deleted
16 /****************************************************************************/
17 
18 // ===========================================================================
19 // included modules
20 // ===========================================================================
21 #include <config.h>
22 
23 #include <netedit/GNENet.h>
24 #include <netedit/netelements/GNEEdge.h>
25 #include <netedit/netelements/GNELane.h>
26 #include <netedit/additionals/GNEShape.h>
27 #include <netedit/additionals/GNEAdditional.h>
28 #include <netedit/demandelements/GNEDemandElement.h>
29 #include <netedit/GNEViewParent.h>
30 #include <netedit/GNEViewNet.h>
31 #include <netedit/frames/GNEFrame.h>
32 
33 
34 #include "GNEChange_Edge.h"
35 
36 // ===========================================================================
37 // FOX-declarations
38 // ===========================================================================
39 FXIMPLEMENT_ABSTRACT(GNEChange_Edge, GNEChange, nullptr, 0)
40 
41 // ===========================================================================
42 // member method definitions
43 // ===========================================================================
44 
45 
46 /// @brief constructor for creating an edge
GNEChange_Edge(GNEEdge * edge,bool forward)47 GNEChange_Edge::GNEChange_Edge(GNEEdge* edge, bool forward):
48     GNEChange(edge->getNet(), forward),
49     myEdge(edge),
50     myEdgeShapeParents(edge->getShapeParents()),
51     myEdgeAdditionalParents(edge->getAdditionalParents()),
52     myEdgeDemandElementParents(edge->getDemandElementParents()),
53     myEdgeShapeChilds(edge->getShapeChilds()),
54     myEdgeAdditionalChilds(edge->getAdditionalChilds()),
55     myEdgeDemandElementChilds(edge->getDemandElementChilds()) {
56     // now save all hierarchical elements of edge's lane
57     for (const auto& i : edge->getLanes()) {
58         myLaneShapeParents.push_back(i->getShapeParents());
59         myLaneAdditionalParents.push_back(i->getAdditionalParents());
60         myLaneDemandElementParents.push_back(i->getDemandElementParents());
61         myLaneShapeChilds.push_back(i->getShapeChilds());
62         myLaneAdditionalChilds.push_back(i->getAdditionalChilds());
63         myLaneDemandElementChilds.push_back(i->getDemandElementChilds());
64     }
65 
66     edge->incRef("GNEChange_Edge");
67 }
68 
69 
~GNEChange_Edge()70 GNEChange_Edge::~GNEChange_Edge() {
71     assert(myEdge);
72     myEdge->decRef("GNEChange_Edge");
73     if (myEdge->unreferenced()) {
74         // show extra information for tests
75         WRITE_DEBUG("Deleting unreferenced " + myEdge->getTagStr() + " '" + myEdge->getID() + "' GNEChange_Edge");
76         delete myEdge;
77     }
78 }
79 
80 
81 void
undo()82 GNEChange_Edge::undo() {
83     if (myForward) {
84         // show extra information for tests
85         WRITE_DEBUG("Removing " + myEdge->getTagStr() + " '" + myEdge->getID() + "' from " + toString(SUMO_TAG_NET));
86         // Remove edge from parent elements
87         for (const auto& i : myEdgeShapeParents) {
88             i->removeEdgeChild(myEdge);
89         }
90         for (const auto& i : myEdgeAdditionalParents) {
91             i->removeEdgeChild(myEdge);
92         }
93         for (const auto& i : myEdgeDemandElementParents) {
94             i->removeEdgeChild(myEdge);
95         }
96         // Remove edge from child elements
97         for (const auto& i : myEdgeShapeChilds) {
98             i->removeEdgeParent(myEdge);
99         }
100         for (const auto& i : myEdgeAdditionalChilds) {
101             i->removeEdgeParent(myEdge);
102         }
103         for (const auto& i : myEdgeDemandElementChilds) {
104             i->removeEdgeParent(myEdge);
105         }
106         // repeat operations for all lane's edge
107         for (int i = 0; i < (int)myEdge->getLanes().size(); i++) {
108             // Remove every lane's edge from parent elements
109             for (const auto& j : myLaneShapeParents.at(i)) {
110                 j->removeLaneChild(myEdge->getLanes().at(i));
111             }
112             for (const auto& j : myLaneAdditionalParents.at(i)) {
113                 j->removeLaneChild(myEdge->getLanes().at(i));
114             }
115             for (const auto& j : myLaneDemandElementParents.at(i)) {
116                 j->removeLaneChild(myEdge->getLanes().at(i));
117             }
118             // Remove every lane's edge from child elements
119             for (const auto& j : myLaneShapeChilds.at(i)) {
120                 j->removeLaneParent(myEdge->getLanes().at(i));
121             }
122             for (const auto& j : myLaneAdditionalChilds.at(i)) {
123                 j->removeLaneParent(myEdge->getLanes().at(i));
124             }
125             for (const auto& j : myLaneDemandElementChilds.at(i)) {
126                 j->removeLaneParent(myEdge->getLanes().at(i));
127             }
128         }
129         // delete edge from net
130         myNet->deleteSingleEdge(myEdge, false);
131     } else {
132         // show extra information for tests
133         WRITE_DEBUG("Adding " + myEdge->getTagStr() + " '" + myEdge->getID() + "' from " + toString(SUMO_TAG_NET));
134         // insert edge into net
135         myNet->insertEdge(myEdge);
136         // add edge in parent elements
137         for (const auto& i : myEdgeShapeParents) {
138             i->addEdgeChild(myEdge);
139         }
140         for (const auto& i : myEdgeAdditionalParents) {
141             i->addEdgeChild(myEdge);
142         }
143         for (const auto& i : myEdgeDemandElementParents) {
144             i->addEdgeChild(myEdge);
145         }
146         // add edge in child elements
147         for (const auto& i : myEdgeShapeChilds) {
148             i->addEdgeParent(myEdge);
149         }
150         for (const auto& i : myEdgeAdditionalChilds) {
151             i->addEdgeParent(myEdge);
152         }
153         for (const auto& i : myEdgeDemandElementChilds) {
154             i->addEdgeParent(myEdge);
155         }
156         // repeat operations for all lane's edge
157         for (int i = 0; i < (int)myEdge->getLanes().size(); i++) {
158             // add lane's edge in parent elements
159             for (const auto& j : myLaneShapeParents.at(i)) {
160                 j->addLaneChild(myEdge->getLanes().at(i));
161             }
162             for (const auto& j : myLaneAdditionalParents.at(i)) {
163                 j->addLaneChild(myEdge->getLanes().at(i));
164             }
165             for (const auto& j : myLaneDemandElementParents.at(i)) {
166                 j->addLaneChild(myEdge->getLanes().at(i));
167             }
168             // add lane's edge in child elements
169             for (const auto& j : myLaneShapeChilds.at(i)) {
170                 j->addLaneParent(myEdge->getLanes().at(i));
171             }
172             for (const auto& j : myLaneAdditionalChilds.at(i)) {
173                 j->addLaneParent(myEdge->getLanes().at(i));
174             }
175             for (const auto& j : myLaneDemandElementChilds.at(i)) {
176                 j->addLaneParent(myEdge->getLanes().at(i));
177             }
178         }
179     }
180     // enable save netElements
181     myNet->requiereSaveNet(true);
182 }
183 
184 
185 void
redo()186 GNEChange_Edge::redo() {
187     if (myForward) {
188         // show extra information for tests
189         WRITE_DEBUG("Adding " + myEdge->getTagStr() + " '" + myEdge->getID() + "' from " + toString(SUMO_TAG_NET));
190         // insert edge into net
191         myNet->insertEdge(myEdge);
192         // add edge in parent elements
193         for (const auto& i : myEdgeShapeParents) {
194             i->addEdgeChild(myEdge);
195         }
196         for (const auto& i : myEdgeAdditionalParents) {
197             i->addEdgeChild(myEdge);
198         }
199         for (const auto& i : myEdgeDemandElementParents) {
200             i->addEdgeChild(myEdge);
201         }
202         // add edge in child elements
203         for (const auto& i : myEdgeShapeChilds) {
204             i->addEdgeParent(myEdge);
205         }
206         for (const auto& i : myEdgeAdditionalChilds) {
207             i->addEdgeParent(myEdge);
208         }
209         for (const auto& i : myEdgeDemandElementChilds) {
210             i->addEdgeParent(myEdge);
211         }
212         // repeat operations for all lane's edge
213         for (int i = 0; i < (int)myEdge->getLanes().size(); i++) {
214             // add lane's edge in parent elements
215             for (const auto& j : myLaneShapeParents.at(i)) {
216                 j->addLaneChild(myEdge->getLanes().at(i));
217             }
218             for (const auto& j : myLaneAdditionalParents.at(i)) {
219                 j->addLaneChild(myEdge->getLanes().at(i));
220             }
221             for (const auto& j : myLaneDemandElementParents.at(i)) {
222                 j->addLaneChild(myEdge->getLanes().at(i));
223             }
224             // add lane's edge in child elements
225             for (const auto& j : myLaneShapeChilds.at(i)) {
226                 j->addLaneParent(myEdge->getLanes().at(i));
227             }
228             for (const auto& j : myLaneAdditionalChilds.at(i)) {
229                 j->addLaneParent(myEdge->getLanes().at(i));
230             }
231             for (const auto& j : myLaneDemandElementChilds.at(i)) {
232                 j->addLaneParent(myEdge->getLanes().at(i));
233             }
234         }
235     } else {
236         // show extra information for tests
237         WRITE_DEBUG("Removing " + myEdge->getTagStr() + " '" + myEdge->getID() + "' from " + toString(SUMO_TAG_NET));
238         // Remove edge from parent elements
239         for (const auto& i : myEdgeShapeParents) {
240             i->removeEdgeChild(myEdge);
241         }
242         for (const auto& i : myEdgeAdditionalParents) {
243             i->removeEdgeChild(myEdge);
244         }
245         for (const auto& i : myEdgeDemandElementParents) {
246             i->removeEdgeChild(myEdge);
247         }
248         // Remove edge from child elements
249         for (const auto& i : myEdgeShapeChilds) {
250             i->removeEdgeParent(myEdge);
251         }
252         for (const auto& i : myEdgeAdditionalChilds) {
253             i->removeEdgeParent(myEdge);
254         }
255         for (const auto& i : myEdgeDemandElementChilds) {
256             i->removeEdgeParent(myEdge);
257         }
258         // repeat operations for all lane's edge
259         for (int i = 0; i < (int)myEdge->getLanes().size(); i++) {
260             // Remove every lane's edge from parent elements
261             for (const auto& j : myLaneShapeParents.at(i)) {
262                 j->removeLaneChild(myEdge->getLanes().at(i));
263             }
264             for (const auto& j : myLaneAdditionalParents.at(i)) {
265                 j->removeLaneChild(myEdge->getLanes().at(i));
266             }
267             for (const auto& j : myLaneDemandElementParents.at(i)) {
268                 j->removeLaneChild(myEdge->getLanes().at(i));
269             }
270             // Remove every lane's edge from child elements
271             for (const auto& j : myLaneShapeChilds.at(i)) {
272                 j->removeLaneParent(myEdge->getLanes().at(i));
273             }
274             for (const auto& j : myLaneAdditionalChilds.at(i)) {
275                 j->removeLaneParent(myEdge->getLanes().at(i));
276             }
277             for (const auto& j : myLaneDemandElementChilds.at(i)) {
278                 j->removeLaneParent(myEdge->getLanes().at(i));
279             }
280         }
281         // delete edge from net
282         myNet->deleteSingleEdge(myEdge, false);
283     }
284     // enable save netElements
285     myNet->requiereSaveNet(true);
286 }
287 
288 
289 FXString
undoName() const290 GNEChange_Edge::undoName() const {
291     if (myForward) {
292         return ("Undo create " + toString(SUMO_TAG_EDGE)).c_str();
293     } else {
294         return ("Undo delete " + toString(SUMO_TAG_EDGE)).c_str();
295     }
296 }
297 
298 
299 FXString
redoName() const300 GNEChange_Edge::redoName() const {
301     if (myForward) {
302         return ("Redo create " + toString(SUMO_TAG_EDGE)).c_str();
303     } else {
304         return ("Redo delete " + toString(SUMO_TAG_EDGE)).c_str();
305     }
306 }
307