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    GNETAZFrame.cpp
11 /// @author  Pablo Alvarez Lopez
12 /// @date    Oct 2018
13 /// @version $Id$
14 ///
15 // The Widget for add TAZ elements
16 /****************************************************************************/
17 
18 // ===========================================================================
19 // included modules
20 // ===========================================================================
21 #include <config.h>
22 
23 #include <utils/foxtools/MFXUtils.h>
24 #include <utils/gui/windows/GUIAppEnum.h>
25 #include <utils/gui/div/GUIDesigns.h>
26 #include <utils/gui/images/GUIIconSubSys.h>
27 #include <utils/xml/SUMOSAXAttributesImpl_Cached.h>
28 #include <netedit/GNENet.h>
29 #include <netedit/GNEViewNet.h>
30 #include <netedit/changes/GNEChange_Additional.h>
31 #include <netedit/netelements/GNEEdge.h>
32 #include <netedit/netelements/GNELane.h>
33 #include <netedit/additionals/GNETAZ.h>
34 #include <netedit/additionals/GNETAZSourceSink.h>
35 #include <netedit/additionals/GNEAdditionalHandler.h>
36 #include <netedit/GNEUndoList.h>
37 
38 #include "GNETAZFrame.h"
39 
40 
41 // ===========================================================================
42 // FOX callback mapping
43 // ===========================================================================
44 
45 FXDEFMAP(GNETAZFrame::TAZParameters) TAZParametersMap[] = {
46     FXMAPFUNC(SEL_COMMAND, MID_GNE_SET_ATTRIBUTE_DIALOG,    GNETAZFrame::TAZParameters::onCmdSetColorAttribute),
47     FXMAPFUNC(SEL_COMMAND, MID_GNE_SET_ATTRIBUTE,           GNETAZFrame::TAZParameters::onCmdSetAttribute),
48     FXMAPFUNC(SEL_COMMAND, MID_HELP,                        GNETAZFrame::TAZParameters::onCmdHelp),
49 };
50 
51 FXDEFMAP(GNETAZFrame::TAZSaveChanges) TAZSaveChangesMap[] = {
52     FXMAPFUNC(SEL_COMMAND,  MID_OK,         GNETAZFrame::TAZSaveChanges::onCmdSaveChanges),
53     FXMAPFUNC(SEL_COMMAND,  MID_CANCEL,     GNETAZFrame::TAZSaveChanges::onCmdCancelChanges),
54 };
55 
56 FXDEFMAP(GNETAZFrame::TAZChildDefaultParameters) TAZChildDefaultParametersMap[] = {
57     FXMAPFUNC(SEL_COMMAND,  MID_GNE_SET_ATTRIBUTE,  GNETAZFrame::TAZChildDefaultParameters::onCmdSetDefaultValues),
58     FXMAPFUNC(SEL_COMMAND,  MID_GNE_SELECT,         GNETAZFrame::TAZChildDefaultParameters::onCmdUseSelectedEdges),
59 };
60 
61 FXDEFMAP(GNETAZFrame::TAZSelectionStatistics) TAZSelectionStatisticsMap[] = {
62     FXMAPFUNC(SEL_COMMAND,  MID_GNE_SET_ATTRIBUTE,  GNETAZFrame::TAZSelectionStatistics::onCmdSetNewValues),
63 };
64 
65 FXDEFMAP(GNETAZFrame::TAZEdgesGraphic) TAZEdgesGraphicMap[] = {
66     FXMAPFUNC(SEL_COMMAND,  MID_CHOOSEN_OPERATION,  GNETAZFrame::TAZEdgesGraphic::onCmdChoosenBy),
67 };
68 
69 // Object implementation
FXIMPLEMENT(GNETAZFrame::TAZParameters,FXGroupBox,TAZParametersMap,ARRAYNUMBER (TAZParametersMap))70 FXIMPLEMENT(GNETAZFrame::TAZParameters,             FXGroupBox,     TAZParametersMap,               ARRAYNUMBER(TAZParametersMap))
71 FXIMPLEMENT(GNETAZFrame::TAZSaveChanges,            FXGroupBox,     TAZSaveChangesMap,              ARRAYNUMBER(TAZSaveChangesMap))
72 FXIMPLEMENT(GNETAZFrame::TAZChildDefaultParameters, FXGroupBox,     TAZChildDefaultParametersMap,   ARRAYNUMBER(TAZChildDefaultParametersMap))
73 FXIMPLEMENT(GNETAZFrame::TAZSelectionStatistics,    FXGroupBox,     TAZSelectionStatisticsMap,      ARRAYNUMBER(TAZSelectionStatisticsMap))
74 FXIMPLEMENT(GNETAZFrame::TAZEdgesGraphic,           FXGroupBox,     TAZEdgesGraphicMap,             ARRAYNUMBER(TAZEdgesGraphicMap))
75 
76 
77 // ===========================================================================
78 // method definitions
79 // ===========================================================================
80 
81 // ---------------------------------------------------------------------------
82 // GNETAZFrame::TAZCurrent - methods
83 // ---------------------------------------------------------------------------
84 
85 GNETAZFrame::TAZCurrent::TAZEdge::TAZEdge(TAZCurrent* TAZCurrentParent, GNEEdge* _edge, GNETAZSourceSink* _TAZSource, GNETAZSourceSink* _TAZSink) :
86     edge(_edge),
87     TAZSource(_TAZSource),
88     TAZSink(_TAZSink),
89     sourceColor(0),
90     sinkColor(0),
91     sourcePlusSinkColor(0),
92     sourceMinusSinkColor(0),
93     myTAZCurrentParent(TAZCurrentParent)
94 { }
95 
96 
~TAZEdge()97 GNETAZFrame::TAZCurrent::TAZEdge::~TAZEdge() {}
98 
99 
100 void
updateColors()101 GNETAZFrame::TAZCurrent::TAZEdge::updateColors() {
102     sourceColor = GNEAttributeCarrier::parse<int>(TAZSource->getAttribute(GNE_ATTR_TAZCOLOR));
103     sinkColor = GNEAttributeCarrier::parse<int>(TAZSink->getAttribute(GNE_ATTR_TAZCOLOR));
104     // Obtain Source+Sink needs more steps. First obtain Source+Sink Weight
105     double sourcePlusSinkWeight = TAZSource->getDepartWeight() + TAZSink->getDepartWeight();
106     // avoid division between zero
107     if ((myTAZCurrentParent->myMaxSourcePlusSinkWeight - myTAZCurrentParent->myMinSourcePlusSinkWeight) == 0) {
108         sourcePlusSinkColor = 0;
109     } else {
110         // calculate percentage relative to the max and min Source+Sink weight
111         double percentage = (sourcePlusSinkWeight - myTAZCurrentParent->myMinSourcePlusSinkWeight) /
112                             (myTAZCurrentParent->myMaxSourcePlusSinkWeight - myTAZCurrentParent->myMinSourcePlusSinkWeight);
113         // convert percentage to a value between [0-9] (because we have only 10 colors)
114         if (percentage >= 1) {
115             sourcePlusSinkColor = 9;
116         } else if (percentage < 0) {
117             sourcePlusSinkColor = 0;
118         } else {
119             sourcePlusSinkColor = (int)(percentage * 10);
120         }
121     }
122     // Obtain Source+Sink needs more steps. First obtain Source-Sink Weight
123     double sourceMinusSinkWeight =  TAZSource->getDepartWeight() - TAZSink->getDepartWeight();
124     // avoid division between zero
125     if ((myTAZCurrentParent->myMaxSourceMinusSinkWeight - myTAZCurrentParent->myMinSourceMinusSinkWeight) == 0) {
126         sourceMinusSinkColor = 0;
127     } else {
128         // calculate percentage relative to the max and min Source-Sink weight
129         double percentage = (sourceMinusSinkWeight - myTAZCurrentParent->myMinSourceMinusSinkWeight) /
130                             (myTAZCurrentParent->myMaxSourceMinusSinkWeight - myTAZCurrentParent->myMinSourceMinusSinkWeight);
131         // convert percentage to a value between [0-9] (because we have only 10 colors)
132         if (percentage >= 1) {
133             sourceMinusSinkColor = 9;
134         } else if (percentage < 0) {
135             sourceMinusSinkColor = 0;
136         } else {
137             sourceMinusSinkColor = (int)(percentage * 10);
138         }
139     }
140 }
141 
142 
TAZCurrent(GNETAZFrame * TAZFrameParent)143 GNETAZFrame::TAZCurrent::TAZCurrent(GNETAZFrame* TAZFrameParent) :
144     FXGroupBox(TAZFrameParent->myContentFrame, "TAZ", GUIDesignGroupBoxFrame),
145     myTAZFrameParent(TAZFrameParent),
146     myEditedTAZ(nullptr),
147     myMaxSourcePlusSinkWeight(0),
148     myMinSourcePlusSinkWeight(-1),
149     myMaxSourceMinusSinkWeight(0),
150     myMinSourceMinusSinkWeight(-1) {
151     // create TAZ label
152     myTAZCurrentLabel = new FXLabel(this, "No TAZ selected", 0, GUIDesignLabelLeft);
153 }
154 
155 
~TAZCurrent()156 GNETAZFrame::TAZCurrent::~TAZCurrent() {}
157 
158 
159 void
setTAZ(GNETAZ * editedTAZ)160 GNETAZFrame::TAZCurrent::setTAZ(GNETAZ* editedTAZ) {
161     // set new current TAZ
162     myEditedTAZ = editedTAZ;
163     // update label and moduls
164     if (myEditedTAZ != nullptr) {
165         myTAZCurrentLabel->setText(("Current TAZ: " + myEditedTAZ->getID()).c_str());
166         // obtain a copy of all edges of the net (to avoid slowdown during manipulations)
167         myNetEdges = myTAZFrameParent->myViewNet->getNet()->retrieveEdges();
168         // obtain a copy of all SELECTED edges of the net (to avoid slowdown during manipulations)
169         mySelectedEdges = myTAZFrameParent->myViewNet->getNet()->retrieveEdges(true);
170         // resfresh TAZ Edges
171         refreshTAZEdges();
172         // hide TAZ parameters
173         myTAZFrameParent->myTAZParameters->hideTAZParametersModul();
174         // hide Netedit parameters
175         myTAZFrameParent->myNeteditAttributes->hideNeteditAttributesModul();
176         // hide drawing shape
177         myTAZFrameParent->myDrawingShape->hideDrawingShape();
178         // show edge common parameters
179         myTAZFrameParent->myTAZCommonStatistics->showTAZCommonStatisticsModul();
180         // show save TAZ Edges
181         myTAZFrameParent->myTAZSaveChanges->showTAZSaveChangesModul();
182         // show edge common parameters
183         myTAZFrameParent->myTAZChildDefaultParameters->showTAZChildDefaultParametersModul();
184         // show Edges graphics
185         myTAZFrameParent->myTAZEdgesGraphic->showTAZEdgesGraphicModul();
186     } else {
187         // show TAZ parameters
188         myTAZFrameParent->myTAZParameters->showTAZParametersModul();
189         // show Netedit parameters
190         myTAZFrameParent->myNeteditAttributes->showNeteditAttributesModul(GNEAttributeCarrier::getTagProperties(SUMO_TAG_TAZ));
191         // show drawing shape
192         myTAZFrameParent->myDrawingShape->showDrawingShape();
193         // hide edge common parameters
194         myTAZFrameParent->myTAZCommonStatistics->hideTAZCommonStatisticsModul();
195         // hide edge common parameters
196         myTAZFrameParent->myTAZChildDefaultParameters->hideTAZChildDefaultParametersModul();
197         // hide Edges graphics
198         myTAZFrameParent->myTAZEdgesGraphic->hideTAZEdgesGraphicModul();
199         // hide save TAZ Edges
200         myTAZFrameParent->myTAZSaveChanges->hideTAZSaveChangesModul();
201         // restore label
202         myTAZCurrentLabel->setText("No TAZ selected");
203         // clear net edges (always the last step due hideTAZEdgesGraphicModul() function)
204         myNetEdges.clear();
205         // clear selected edges
206         mySelectedEdges.clear();
207         // reset all weight values
208         myMaxSourcePlusSinkWeight = 0;
209         myMinSourcePlusSinkWeight = -1;
210         myMaxSourceMinusSinkWeight = 0;
211         myMinSourceMinusSinkWeight = -1;
212     }
213 }
214 
215 
216 GNETAZ*
getTAZ() const217 GNETAZFrame::TAZCurrent::getTAZ() const {
218     return myEditedTAZ;
219 }
220 
221 
222 bool
isTAZEdge(GNEEdge * edge) const223 GNETAZFrame::TAZCurrent::isTAZEdge(GNEEdge* edge) const {
224     // simply iterate over edges and check edge parameter
225     for (const auto& i : myTAZEdges) {
226         if (i.edge == edge) {
227             return true;
228         }
229     }
230     // not found, then return false
231     return false;
232 }
233 
234 
235 const std::vector<GNEEdge*>&
getNetEdges() const236 GNETAZFrame::TAZCurrent::getNetEdges() const {
237     return myNetEdges;
238 }
239 
240 
241 const std::vector<GNEEdge*>&
getSelectedEdges() const242 GNETAZFrame::TAZCurrent::getSelectedEdges() const {
243     return mySelectedEdges;
244 }
245 
246 
247 const std::vector<GNETAZFrame::TAZCurrent::TAZEdge>&
getTAZEdges() const248 GNETAZFrame::TAZCurrent::getTAZEdges() const {
249     return myTAZEdges;
250 }
251 
252 
253 void
refreshTAZEdges()254 GNETAZFrame::TAZCurrent::refreshTAZEdges() {
255     // clear all curren TAZEdges
256     myTAZEdges.clear();
257     // clear weight values
258     myMaxSourcePlusSinkWeight = 0;
259     myMinSourcePlusSinkWeight = -1;
260     myMaxSourceMinusSinkWeight = 0;
261     myMinSourceMinusSinkWeight = -1;
262     // only refresh if we're editing an TAZ
263     if (myEditedTAZ) {
264         // iterate over additional childs and create TAZEdges
265         for (const auto& i : myEditedTAZ->getAdditionalChilds()) {
266             addTAZChild(dynamic_cast<GNETAZSourceSink*>(i));
267         }
268         // update colors after add all edges
269         for (auto& i : myTAZEdges) {
270             i.updateColors();
271         }
272         // update edge colors
273         myTAZFrameParent->myTAZEdgesGraphic->updateEdgeColors();
274     }
275 }
276 
277 
278 void
addTAZChild(GNETAZSourceSink * sourceSink)279 GNETAZFrame::TAZCurrent::addTAZChild(GNETAZSourceSink* sourceSink) {
280     // first make sure that additional is an TAZ Source or Sink
281     if (sourceSink && ((sourceSink->getTagProperty().getTag() == SUMO_TAG_TAZSOURCE) || (sourceSink->getTagProperty().getTag() == SUMO_TAG_TAZSINK))) {
282         GNEEdge* edge = myTAZFrameParent->myViewNet->getNet()->retrieveEdge(sourceSink->getAttribute(SUMO_ATTR_EDGE));
283         // first check if TAZEdge has to be created
284         bool createTAZEdge = true;
285         for (auto& i : myTAZEdges) {
286             if (i.edge == edge) {
287                 createTAZEdge = false;
288                 // update TAZ Source or Sink
289                 if (sourceSink->getTagProperty().getTag() == SUMO_TAG_TAZSOURCE) {
290                     i.TAZSource = sourceSink;
291                 } else {
292                     i.TAZSink = sourceSink;
293                 }
294             }
295         }
296         // check if additional has to be created
297         if (createTAZEdge) {
298             if (sourceSink->getTagProperty().getTag() == SUMO_TAG_TAZSOURCE) {
299                 myTAZEdges.push_back(TAZEdge(this, edge, sourceSink, nullptr));
300             } else {
301                 myTAZEdges.push_back(TAZEdge(this, edge, nullptr, sourceSink));
302             }
303         }
304         // recalculate weights
305         myMaxSourcePlusSinkWeight = 0;
306         myMinSourcePlusSinkWeight = -1;
307         myMaxSourceMinusSinkWeight = 0;
308         myMinSourceMinusSinkWeight = -1;
309         for (const auto& i : myTAZEdges) {
310             // make sure that both TAZ Source and Sink exist
311             if (i.TAZSource && i.TAZSink) {
312                 // obtain source plus sink
313                 double sourcePlusSink = i.TAZSource->getDepartWeight() + i.TAZSink->getDepartWeight();
314                 // check myMaxSourcePlusSinkWeight
315                 if (sourcePlusSink > myMaxSourcePlusSinkWeight) {
316                     myMaxSourcePlusSinkWeight = sourcePlusSink;
317                 }
318                 // check myMinSourcePlusSinkWeight
319                 if ((myMinSourcePlusSinkWeight == -1) || (sourcePlusSink < myMinSourcePlusSinkWeight)) {
320                     myMinSourcePlusSinkWeight = sourcePlusSink;
321                 }
322                 // obtain source minus sink
323                 double sourceMinusSink = i.TAZSource->getDepartWeight() - i.TAZSink->getDepartWeight();
324                 // use valor absolute
325                 if (sourceMinusSink < 0) {
326                     sourceMinusSink *= -1;
327                 }
328                 // check myMaxSourcePlusSinkWeight
329                 if (sourceMinusSink > myMaxSourceMinusSinkWeight) {
330                     myMaxSourceMinusSinkWeight = sourceMinusSink;
331                 }
332                 // check myMinSourcePlusSinkWeight
333                 if ((myMinSourceMinusSinkWeight == -1) || (sourceMinusSink < myMinSourceMinusSinkWeight)) {
334                     myMinSourceMinusSinkWeight = sourceMinusSink;
335                 }
336             }
337         }
338     } else {
339         throw ProcessError("Invalid TAZ Child");
340     }
341 }
342 
343 // ---------------------------------------------------------------------------
344 // GNETAZFrame::TAZCommonStatistics - methods
345 // ---------------------------------------------------------------------------
346 
TAZCommonStatistics(GNETAZFrame * TAZFrameParent)347 GNETAZFrame::TAZCommonStatistics::TAZCommonStatistics(GNETAZFrame* TAZFrameParent) :
348     FXGroupBox(TAZFrameParent->myContentFrame, "TAZ Statistics", GUIDesignGroupBoxFrame),
349     myTAZFrameParent(TAZFrameParent) {
350     // create label for statistics
351     myStatisticsLabel = new FXLabel(this, "Statistics", 0, GUIDesignLabelFrameInformation);
352 }
353 
354 
~TAZCommonStatistics()355 GNETAZFrame::TAZCommonStatistics::~TAZCommonStatistics() {}
356 
357 
358 void
showTAZCommonStatisticsModul()359 GNETAZFrame::TAZCommonStatistics::showTAZCommonStatisticsModul() {
360     // always update statistics after show
361     updateStatistics();
362     show();
363 }
364 
365 
366 void
hideTAZCommonStatisticsModul()367 GNETAZFrame::TAZCommonStatistics::hideTAZCommonStatisticsModul() {
368     hide();
369 }
370 
371 
372 void
updateStatistics()373 GNETAZFrame::TAZCommonStatistics::updateStatistics() {
374     if (myTAZFrameParent->myTAZCurrent->getTAZ()) {
375         // declare ostringstream for statistics
376         std::ostringstream information;
377         information
378                 << "- Number of Edges: " << toString(myTAZFrameParent->myTAZCurrent->getTAZ()->getAdditionalChilds().size() / 2) << "\n"
379                 << "- Min source: " << myTAZFrameParent->myTAZCurrent->getTAZ()->getAttribute(GNE_ATTR_MIN_SOURCE) << "\n"
380                 << "- Max source: " << myTAZFrameParent->myTAZCurrent->getTAZ()->getAttribute(GNE_ATTR_MAX_SOURCE) << "\n"
381                 << "- Average source: " << myTAZFrameParent->myTAZCurrent->getTAZ()->getAttribute(GNE_ATTR_AVERAGE_SOURCE) << "\n"
382                 << "\n"
383                 << "- Min sink: " << myTAZFrameParent->myTAZCurrent->getTAZ()->getAttribute(GNE_ATTR_MIN_SINK) << "\n"
384                 << "- Max sink: " << myTAZFrameParent->myTAZCurrent->getTAZ()->getAttribute(GNE_ATTR_MAX_SINK) << "\n"
385                 << "- Average sink: " << myTAZFrameParent->myTAZCurrent->getTAZ()->getAttribute(GNE_ATTR_AVERAGE_SINK);
386         // set new label
387         myStatisticsLabel->setText(information.str().c_str());
388     } else {
389         myStatisticsLabel->setText("No TAZ Selected");
390     }
391 }
392 
393 // ---------------------------------------------------------------------------
394 // GNETAZFrame::TAZSaveChanges - methods
395 // ---------------------------------------------------------------------------
396 
TAZSaveChanges(GNETAZFrame * TAZFrameParent)397 GNETAZFrame::TAZSaveChanges::TAZSaveChanges(GNETAZFrame* TAZFrameParent) :
398     FXGroupBox(TAZFrameParent->myContentFrame, "Modifications", GUIDesignGroupBoxFrame),
399     myTAZFrameParent(TAZFrameParent) {
400     // Create groupbox for save changes
401     mySaveChangesButton = new FXButton(this, "Save changes", GUIIconSubSys::getIcon(ICON_SAVE), this, MID_OK, GUIDesignButton);
402     mySaveChangesButton->disable();
403     // Create groupbox cancel changes
404     myCancelChangesButton = new FXButton(this, "Cancel changes", GUIIconSubSys::getIcon(ICON_CANCEL), this, MID_CANCEL, GUIDesignButton);
405     myCancelChangesButton->disable();
406 }
407 
408 
~TAZSaveChanges()409 GNETAZFrame::TAZSaveChanges::~TAZSaveChanges() {}
410 
411 
412 void
showTAZSaveChangesModul()413 GNETAZFrame::TAZSaveChanges::showTAZSaveChangesModul() {
414     show();
415 }
416 
417 
418 void
hideTAZSaveChangesModul()419 GNETAZFrame::TAZSaveChanges::hideTAZSaveChangesModul() {
420     // cancel changes before hidding modul
421     onCmdCancelChanges(0, 0, 0);
422     hide();
423 }
424 
425 
426 void
enableButtonsAndBeginUndoList()427 GNETAZFrame::TAZSaveChanges::enableButtonsAndBeginUndoList() {
428     // check that save changes is disabled
429     if (!mySaveChangesButton->isEnabled()) {
430         // enable mySaveChangesButton and myCancelChangesButton
431         mySaveChangesButton->enable();
432         myCancelChangesButton->enable();
433         // start undo list set
434         myTAZFrameParent->myViewNet->getUndoList()->p_begin("TAZ attributes");
435     }
436 }
437 
438 
439 bool
isChangesPending() const440 GNETAZFrame::TAZSaveChanges::isChangesPending() const {
441     // simply check if save Changes Button is enabled
442     return mySaveChangesButton->isEnabled();
443 }
444 
445 
446 long
onCmdSaveChanges(FXObject *,FXSelector,void *)447 GNETAZFrame::TAZSaveChanges::onCmdSaveChanges(FXObject*, FXSelector, void*) {
448     // check that save changes is enabled
449     if (mySaveChangesButton->isEnabled()) {
450         // disable mySaveChangesButton and myCancelChangesButtonand
451         mySaveChangesButton->disable();
452         myCancelChangesButton->disable();
453         // finish undo list set
454         myTAZFrameParent->myViewNet->getUndoList()->p_end();
455     }
456     return 1;
457 }
458 
459 
460 long
onCmdCancelChanges(FXObject *,FXSelector,void *)461 GNETAZFrame::TAZSaveChanges::onCmdCancelChanges(FXObject*, FXSelector, void*) {
462     // check that save changes is enabled
463     if (mySaveChangesButton->isEnabled()) {
464         // disable buttons
465         mySaveChangesButton->disable();
466         myCancelChangesButton->disable();
467         // abort undo list
468         myTAZFrameParent->myViewNet->getUndoList()->p_abort();
469         // always refresh TAZ Edges after removing TAZSources/Sinks
470         myTAZFrameParent->myTAZCurrent->refreshTAZEdges();
471         // update use edges button
472         myTAZFrameParent->myTAZChildDefaultParameters->updateSelectEdgesButton();
473     }
474     return 1;
475 }
476 
477 // ---------------------------------------------------------------------------
478 // GNETAZFrame::TAZChildDefaultParameters - methods
479 // ---------------------------------------------------------------------------
480 
TAZChildDefaultParameters(GNETAZFrame * TAZFrameParent)481 GNETAZFrame::TAZChildDefaultParameters::TAZChildDefaultParameters(GNETAZFrame* TAZFrameParent) :
482     FXGroupBox(TAZFrameParent->myContentFrame, "TAZ Sources/Sinks", GUIDesignGroupBoxFrame),
483     myTAZFrameParent(TAZFrameParent),
484     myDefaultTAZSourceWeight(1),
485     myDefaultTAZSinkWeight(1) {
486     // create checkbox for toogle membership
487     FXHorizontalFrame* toogleMembershipFrame = new FXHorizontalFrame(this, GUIDesignAuxiliarHorizontalFrame);
488     new FXLabel(toogleMembershipFrame, "Membership", 0, GUIDesignLabelAttribute);
489     myToggleMembership = new FXCheckButton(toogleMembershipFrame, "Toggle", this, MID_GNE_SET_ATTRIBUTE, GUIDesignCheckButtonAttribute);
490     // by default enabled
491     myToggleMembership->setCheck(TRUE);
492     // create default TAZ Source weight
493     myDefaultTAZSourceFrame = new FXHorizontalFrame(this, GUIDesignAuxiliarHorizontalFrame);
494     new FXLabel(myDefaultTAZSourceFrame, "New source", 0, GUIDesignLabelAttribute);
495     myTextFieldDefaultValueTAZSources = new FXTextField(myDefaultTAZSourceFrame, GUIDesignTextFieldNCol, this, MID_GNE_SET_ATTRIBUTE, GUIDesignTextFieldReal);
496     myTextFieldDefaultValueTAZSources->setText("1");
497     // create default TAZ Sink weight
498     myDefaultTAZSinkFrame = new FXHorizontalFrame(this, GUIDesignAuxiliarHorizontalFrame);
499     new FXLabel(myDefaultTAZSinkFrame, "New sink", 0, GUIDesignLabelAttribute);
500     myTextFieldDefaultValueTAZSinks = new FXTextField(myDefaultTAZSinkFrame, GUIDesignTextFieldNCol, this, MID_GNE_SET_ATTRIBUTE, GUIDesignTextFieldReal);
501     myTextFieldDefaultValueTAZSinks->setText("1");
502     // Create button for use selected edges
503     myUseSelectedEdges = new FXButton(this, "Use selected edges", nullptr, this, MID_GNE_SELECT, GUIDesignButton);
504     // Create information label
505     std::ostringstream information;
506     information
507             << "- Toogle Membership:\n"
508             << "  Create new Sources/Sinks\n"
509             << "  with given weights.";
510     myInformationLabel = new FXLabel(this, information.str().c_str(), 0, GUIDesignLabelFrameInformation);
511 }
512 
513 
~TAZChildDefaultParameters()514 GNETAZFrame::TAZChildDefaultParameters::~TAZChildDefaultParameters() {}
515 
516 
517 void
showTAZChildDefaultParametersModul()518 GNETAZFrame::TAZChildDefaultParameters::showTAZChildDefaultParametersModul() {
519     // check if TAZ selection Statistics Modul has to be shown
520     if (myToggleMembership->getCheck() == FALSE) {
521         myTAZFrameParent->myTAZSelectionStatistics->showTAZSelectionStatisticsModul();
522     } else {
523         myTAZFrameParent->myTAZSelectionStatistics->hideTAZSelectionStatisticsModul();
524     }
525     // update selected button
526     updateSelectEdgesButton();
527     // show modul
528     show();
529 }
530 
531 
532 void
hideTAZChildDefaultParametersModul()533 GNETAZFrame::TAZChildDefaultParameters::hideTAZChildDefaultParametersModul() {
534     // hide TAZ Selection Statistics Modul
535     myTAZFrameParent->myTAZSelectionStatistics->hideTAZSelectionStatisticsModul();
536     // hide modul
537     hide();
538 }
539 
540 
541 void
updateSelectEdgesButton()542 GNETAZFrame::TAZChildDefaultParameters::updateSelectEdgesButton() {
543     if (myToggleMembership->getCheck() == TRUE) {
544         // check if use selected edges has to be enabled
545         if (myTAZFrameParent->myTAZCurrent->getSelectedEdges().size() > 0) {
546             myUseSelectedEdges->setText("Use selected edges");
547             myUseSelectedEdges->enable();
548         } else if (myTAZFrameParent->myTAZCurrent->getTAZEdges().size() > 0) {
549             myUseSelectedEdges->setText("Remove all edges");
550             myUseSelectedEdges->enable();
551         } else {
552             myUseSelectedEdges->setText("Use selected edges");
553             myUseSelectedEdges->disable();
554         }
555     } else if (myTAZFrameParent->getTAZCurrentModul()->getTAZEdges().size() > 0) {
556         // enable myUseSelectedEdges button
557         myUseSelectedEdges->enable();
558         // update mySelectEdgesOfSelection label
559         if (myTAZFrameParent->myTAZSelectionStatistics->getEdgeAndTAZChildsSelected().size() == 0) {
560             // check if all edges of TAZChilds are selected
561             bool allSelected = true;
562             for (const auto& i : myTAZFrameParent->getTAZCurrentModul()->getTAZEdges()) {
563                 if (!i.edge->isAttributeCarrierSelected()) {
564                     allSelected = false;
565                 }
566             }
567             if (allSelected) {
568                 myUseSelectedEdges->setText("Remove all edges from selection");
569             } else {
570                 myUseSelectedEdges->setText("Add all edges to selection");
571             }
572         } else if (myTAZFrameParent->myTAZSelectionStatistics->getEdgeAndTAZChildsSelected().size() == 1) {
573             if (myTAZFrameParent->myTAZSelectionStatistics->getEdgeAndTAZChildsSelected().front().edge->isAttributeCarrierSelected()) {
574                 myUseSelectedEdges->setText("Remove edge from selection");
575             } else {
576                 myUseSelectedEdges->setText("Add edge to selection");
577             }
578         } else {
579             // check if all edges of TAZChilds selected are selected
580             bool allSelected = true;
581             for (const auto& i : myTAZFrameParent->myTAZSelectionStatistics->getEdgeAndTAZChildsSelected()) {
582                 if (!i.edge->isAttributeCarrierSelected()) {
583                     allSelected = false;
584                 }
585             }
586             if (allSelected) {
587                 myUseSelectedEdges->setText(("Remove " + toString(myTAZFrameParent->myTAZSelectionStatistics->getEdgeAndTAZChildsSelected().size()) + " from to selection").c_str());
588             } else {
589                 myUseSelectedEdges->setText(("Add " + toString(myTAZFrameParent->myTAZSelectionStatistics->getEdgeAndTAZChildsSelected().size()) + " edges to selection").c_str());
590             }
591         }
592     } else {
593         // TAZ doesn't have childs, then disable button
594         myUseSelectedEdges->disable();
595     }
596 }
597 
598 
599 double
getDefaultTAZSourceWeight() const600 GNETAZFrame::TAZChildDefaultParameters::getDefaultTAZSourceWeight() const {
601     return myDefaultTAZSourceWeight;
602 }
603 
604 
605 double
getDefaultTAZSinkWeight() const606 GNETAZFrame::TAZChildDefaultParameters::getDefaultTAZSinkWeight() const {
607     return myDefaultTAZSinkWeight;
608 }
609 
610 
611 bool
getToggleMembership() const612 GNETAZFrame::TAZChildDefaultParameters::getToggleMembership() const {
613     return (myToggleMembership->getCheck() == TRUE);
614 }
615 
616 
617 long
onCmdSetDefaultValues(FXObject * obj,FXSelector,void *)618 GNETAZFrame::TAZChildDefaultParameters::onCmdSetDefaultValues(FXObject* obj, FXSelector, void*) {
619     // find edited object
620     if (obj == myToggleMembership) {
621         // first clear selected edges
622         myTAZFrameParent->myTAZSelectionStatistics->clearSelectedEdges();
623         // set text of myToggleMembership
624         if (myToggleMembership->getCheck() == TRUE) {
625             myToggleMembership->setText("toogle");
626             // show TAZSource/Sink Frames
627             myDefaultTAZSourceFrame->show();
628             myDefaultTAZSinkFrame->show();
629             // update information label
630             std::ostringstream information;
631             information
632                     << "- Toogle Membership:\n"
633                     << "  Create new Sources/Sinks\n"
634                     << "  with given weights.";
635             myInformationLabel->setText(information.str().c_str());
636             // hide TAZSelectionStatistics
637             myTAZFrameParent->myTAZSelectionStatistics->hideTAZSelectionStatisticsModul();
638             // check if use selected edges has to be enabled
639             if (myTAZFrameParent->myTAZCurrent->getSelectedEdges().size() > 0) {
640                 myUseSelectedEdges->setText("Use selected edges");
641             } else if (myTAZFrameParent->myTAZCurrent->getTAZEdges().size() > 0) {
642                 myUseSelectedEdges->setText("Remove all edges");
643             } else {
644                 myUseSelectedEdges->setText("Use selected edges");
645                 myUseSelectedEdges->disable();
646             }
647         } else {
648             myToggleMembership->setText("keep");
649             // hide TAZSource/Sink Frames
650             myDefaultTAZSourceFrame->hide();
651             myDefaultTAZSinkFrame->hide();
652             // update information label
653             std::ostringstream information;
654             information
655                     << "- Keep Membership:\n"
656                     << "  Select Sources/Sinks.\n"
657                     << "- Press ESC to clear\n"
658                     << "  current selection.";
659             myInformationLabel->setText(information.str().c_str());
660             // show TAZSelectionStatistics
661             myTAZFrameParent->myTAZSelectionStatistics->showTAZSelectionStatisticsModul();
662         }
663         // update button
664         updateSelectEdgesButton();
665     } else if (obj == myTextFieldDefaultValueTAZSources) {
666         // check if given value is valid
667         if (GNEAttributeCarrier::canParse<double>(myTextFieldDefaultValueTAZSources->getText().text())) {
668             myDefaultTAZSourceWeight = GNEAttributeCarrier::parse<double>(myTextFieldDefaultValueTAZSources->getText().text());
669             // check if myDefaultTAZSourceWeight is greather than 0
670             if (myDefaultTAZSourceWeight >= 0) {
671                 // set valid color
672                 myTextFieldDefaultValueTAZSources->setTextColor(FXRGB(0, 0, 0));
673             } else {
674                 // set invalid color
675                 myTextFieldDefaultValueTAZSources->setTextColor(FXRGB(255, 0, 0));
676                 myDefaultTAZSourceWeight = 1;
677             }
678         } else {
679             // set invalid color
680             myTextFieldDefaultValueTAZSources->setTextColor(FXRGB(255, 0, 0));
681             myDefaultTAZSourceWeight = 1;
682         }
683     } else if (obj == myTextFieldDefaultValueTAZSinks) {
684         // check if given value is valid
685         if (GNEAttributeCarrier::canParse<double>(myTextFieldDefaultValueTAZSinks->getText().text())) {
686             myDefaultTAZSinkWeight = GNEAttributeCarrier::parse<double>(myTextFieldDefaultValueTAZSinks->getText().text());
687             // check if myDefaultTAZSinkWeight is greather than 0
688             if (myDefaultTAZSinkWeight >= 0) {
689                 // set valid color
690                 myTextFieldDefaultValueTAZSinks->setTextColor(FXRGB(0, 0, 0));
691             } else {
692                 // set invalid color
693                 myTextFieldDefaultValueTAZSinks->setTextColor(FXRGB(255, 0, 0));
694                 myDefaultTAZSinkWeight = 1;
695             }
696         } else {
697             // set invalid color
698             myTextFieldDefaultValueTAZSinks->setTextColor(FXRGB(255, 0, 0));
699             myDefaultTAZSinkWeight = 1;
700         }
701     }
702     return 1;
703 }
704 
705 
706 long
onCmdUseSelectedEdges(FXObject *,FXSelector,void *)707 GNETAZFrame::TAZChildDefaultParameters::onCmdUseSelectedEdges(FXObject*, FXSelector, void*) {
708     // select edge or create new TAZ Source/Child, depending of myToggleMembership
709     if (myToggleMembership->getCheck() == TRUE) {
710         // first drop all edges
711         myTAZFrameParent->dropTAZMembers();
712         // iterate over selected edges and add it as TAZMember
713         for (const auto& i : myTAZFrameParent->myTAZCurrent->getSelectedEdges()) {
714             myTAZFrameParent->addOrRemoveTAZMember(i);
715         }
716         // update selected button
717         updateSelectEdgesButton();
718     } else {
719         if (myTAZFrameParent->myTAZSelectionStatistics->getEdgeAndTAZChildsSelected().size() == 0) {
720             // first check if all TAZEdges are selected
721             bool allSelected = true;
722             for (const auto& i : myTAZFrameParent->getTAZCurrentModul()->getTAZEdges()) {
723                 if (!i.edge->isAttributeCarrierSelected()) {
724                     allSelected = false;
725                 }
726             }
727             // select or unselect all depending of allSelected
728             if (allSelected) {
729                 // remove form selection all TAZEdges
730                 for (const auto& i : myTAZFrameParent->getTAZCurrentModul()->getTAZEdges()) {
731                     // enable save button
732                     myTAZFrameParent->myTAZSaveChanges->enableButtonsAndBeginUndoList();
733                     // change attribute selected
734                     i.edge->setAttribute(GNE_ATTR_SELECTED, "false", myTAZFrameParent->myViewNet->getUndoList());
735                 }
736             } else {
737                 // add to selection all TAZEdges
738                 for (const auto& i : myTAZFrameParent->getTAZCurrentModul()->getTAZEdges()) {
739                     // enable save button
740                     myTAZFrameParent->myTAZSaveChanges->enableButtonsAndBeginUndoList();
741                     // change attribute selected
742                     i.edge->setAttribute(GNE_ATTR_SELECTED, "true", myTAZFrameParent->myViewNet->getUndoList());
743                 }
744             }
745         } else {
746             // first check if all TAZEdges are selected
747             bool allSelected = true;
748             for (const auto& i : myTAZFrameParent->myTAZSelectionStatistics->getEdgeAndTAZChildsSelected()) {
749                 if (!i.edge->isAttributeCarrierSelected()) {
750                     allSelected = false;
751                 }
752             }
753             // select or unselect all depending of allSelected
754             if (allSelected) {
755                 // only remove from selection selected TAZEdges
756                 for (const auto& i : myTAZFrameParent->myTAZSelectionStatistics->getEdgeAndTAZChildsSelected()) {
757                     if (i.edge->isAttributeCarrierSelected()) {
758                         // enable save button
759                         myTAZFrameParent->myTAZSaveChanges->enableButtonsAndBeginUndoList();
760                         // change attribute selected
761                         i.edge->setAttribute(GNE_ATTR_SELECTED, "false", myTAZFrameParent->myViewNet->getUndoList());
762                     }
763                 }
764             } else {
765                 // only add to selection selected TAZEdges
766                 for (const auto& i : myTAZFrameParent->myTAZSelectionStatistics->getEdgeAndTAZChildsSelected()) {
767                     if (!i.edge->isAttributeCarrierSelected()) {
768                         // enable save button
769                         myTAZFrameParent->myTAZSaveChanges->enableButtonsAndBeginUndoList();
770                         // change attribute selected
771                         i.edge->setAttribute(GNE_ATTR_SELECTED, "true", myTAZFrameParent->myViewNet->getUndoList());
772                     }
773                 }
774             }
775         }
776     }
777     // update selection button
778     myTAZFrameParent->myTAZChildDefaultParameters->updateSelectEdgesButton();
779     // update view net
780     myTAZFrameParent->myViewNet->update();
781     return 1;
782 }
783 
784 // ---------------------------------------------------------------------------
785 // GNETAZFrame::TAZSelectionStatistics - methods
786 // ---------------------------------------------------------------------------
787 
TAZSelectionStatistics(GNETAZFrame * TAZFrameParent)788 GNETAZFrame::TAZSelectionStatistics::TAZSelectionStatistics(GNETAZFrame* TAZFrameParent) :
789     FXGroupBox(TAZFrameParent->myContentFrame, "Selection Statistics", GUIDesignGroupBoxFrame),
790     myTAZFrameParent(TAZFrameParent) {
791     // create default TAZ Source weight
792     myTAZSourceFrame = new FXHorizontalFrame(this, GUIDesignAuxiliarHorizontalFrame);
793     new FXLabel(myTAZSourceFrame, "Source", 0, GUIDesignLabelAttribute);
794     myTextFieldTAZSourceWeight = new FXTextField(myTAZSourceFrame, GUIDesignTextFieldNCol, this, MID_GNE_SET_ATTRIBUTE, GUIDesignTextFieldReal);
795     myTAZSourceFrame->hide();
796     // create default TAZ Sink weight
797     myTAZSinkFrame = new FXHorizontalFrame(this, GUIDesignAuxiliarHorizontalFrame);
798     new FXLabel(myTAZSinkFrame, "Sink", 0, GUIDesignLabelAttribute);
799     myTextFieldTAZSinkWeight = new FXTextField(myTAZSinkFrame, GUIDesignTextFieldNCol, this, MID_GNE_SET_ATTRIBUTE, GUIDesignTextFieldReal);
800     myTAZSinkFrame->hide();
801     // create label for statistics
802     myStatisticsLabel = new FXLabel(this, "Statistics", 0, GUIDesignLabelFrameInformation);
803 }
804 
805 
~TAZSelectionStatistics()806 GNETAZFrame::TAZSelectionStatistics::~TAZSelectionStatistics() {}
807 
808 
809 void
showTAZSelectionStatisticsModul()810 GNETAZFrame::TAZSelectionStatistics::showTAZSelectionStatisticsModul() {
811     // update Statistics before show
812     updateStatistics();
813     show();
814 }
815 
816 
817 void
hideTAZSelectionStatisticsModul()818 GNETAZFrame::TAZSelectionStatistics::hideTAZSelectionStatisticsModul() {
819     // clear childs before hide
820     clearSelectedEdges();
821     hide();
822 }
823 
824 
825 bool
selectEdge(const TAZCurrent::TAZEdge & TAZEdge)826 GNETAZFrame::TAZSelectionStatistics::selectEdge(const TAZCurrent::TAZEdge& TAZEdge) {
827     // find TAZEdge using edge as criterium wasn't previously selected
828     for (const auto& i : myEdgeAndTAZChildsSelected) {
829         if (i.edge == TAZEdge.edge) {
830             throw ProcessError("TAZEdge already selected");
831         }
832     }
833     // add edge and their TAZ Childs into myTAZChildSelected
834     myEdgeAndTAZChildsSelected.push_back(TAZEdge);
835     // always update statistics after insertion
836     updateStatistics();
837     // update edge colors
838     myTAZFrameParent->myTAZEdgesGraphic->updateEdgeColors();
839     // update selection button
840     myTAZFrameParent->myTAZChildDefaultParameters->updateSelectEdgesButton();
841     return true;
842 }
843 
844 
845 bool
unselectEdge(GNEEdge * edge)846 GNETAZFrame::TAZSelectionStatistics::unselectEdge(GNEEdge* edge) {
847     if (edge) {
848         // find TAZEdge using edge as criterium
849         for (auto i = myEdgeAndTAZChildsSelected.begin(); i != myEdgeAndTAZChildsSelected.end(); i++) {
850             if (i->edge == edge) {
851                 myEdgeAndTAZChildsSelected.erase(i);
852                 // always update statistics after insertion
853                 updateStatistics();
854                 // update edge colors
855                 myTAZFrameParent->myTAZEdgesGraphic->updateEdgeColors();
856                 // update selection button
857                 myTAZFrameParent->myTAZChildDefaultParameters->updateSelectEdgesButton();
858                 return true;
859             }
860         }
861         // throw exception if edge wasn't found
862         throw ProcessError("edge wasn't found");
863     } else {
864         throw ProcessError("Invalid edge");
865     }
866 }
867 
868 
869 bool
isEdgeSelected(GNEEdge * edge)870 GNETAZFrame::TAZSelectionStatistics::isEdgeSelected(GNEEdge* edge) {
871     // find TAZEdge using edge as criterium
872     for (const auto& i : myEdgeAndTAZChildsSelected) {
873         if (i.edge == edge) {
874             return true;
875         }
876     }
877     // edge wasn't found, then return false
878     return false;
879 }
880 
881 
882 void
clearSelectedEdges()883 GNETAZFrame::TAZSelectionStatistics::clearSelectedEdges() {
884     // clear all selected edges (and the TAZ Childs)
885     myEdgeAndTAZChildsSelected.clear();
886     // always update statistics after clear edges
887     updateStatistics();
888     // update edge colors
889     myTAZFrameParent->myTAZEdgesGraphic->updateEdgeColors();
890     // update selection button
891     myTAZFrameParent->myTAZChildDefaultParameters->updateSelectEdgesButton();
892 }
893 
894 
895 const std::vector<GNETAZFrame::TAZCurrent::TAZEdge>&
getEdgeAndTAZChildsSelected() const896 GNETAZFrame::TAZSelectionStatistics::getEdgeAndTAZChildsSelected() const {
897     return myEdgeAndTAZChildsSelected;
898 }
899 
900 
901 long
onCmdSetNewValues(FXObject * obj,FXSelector,void *)902 GNETAZFrame::TAZSelectionStatistics::onCmdSetNewValues(FXObject* obj, FXSelector, void*) {
903     if (obj == myTextFieldTAZSourceWeight) {
904         // check if given value is valid
905         if (GNEAttributeCarrier::canParse<double>(myTextFieldTAZSourceWeight->getText().text())) {
906             double newTAZSourceWeight = GNEAttributeCarrier::parse<double>(myTextFieldTAZSourceWeight->getText().text());
907             // check if myDefaultTAZSourceWeight is greather than 0
908             if (newTAZSourceWeight >= 0) {
909                 // set valid color in TextField
910                 myTextFieldTAZSourceWeight->setTextColor(FXRGB(0, 0, 0));
911                 // enable save button
912                 myTAZFrameParent->myTAZSaveChanges->enableButtonsAndBeginUndoList();
913                 // update weight of all TAZSources
914                 for (const auto&  i : myEdgeAndTAZChildsSelected) {
915                     i.TAZSource->setAttribute(SUMO_ATTR_WEIGHT, myTextFieldTAZSourceWeight->getText().text(), myTAZFrameParent->myViewNet->getUndoList());
916                 }
917                 // refresh TAZ Edges
918                 myTAZFrameParent->getTAZCurrentModul()->refreshTAZEdges();
919             } else {
920                 // set invalid color
921                 myTextFieldTAZSourceWeight->setTextColor(FXRGB(255, 0, 0));
922             }
923         } else {
924             // set invalid color
925             myTextFieldTAZSourceWeight->setTextColor(FXRGB(255, 0, 0));
926         }
927     } else if (obj == myTextFieldTAZSinkWeight) {
928         // check if given value is valid
929         if (GNEAttributeCarrier::canParse<double>(myTextFieldTAZSinkWeight->getText().text())) {
930             double newTAZSinkWeight = GNEAttributeCarrier::parse<double>(myTextFieldTAZSinkWeight->getText().text());
931             // check if myDefaultTAZSinkWeight is greather than 0
932             if (newTAZSinkWeight >= 0) {
933                 // set valid color in TextField
934                 myTextFieldTAZSinkWeight->setTextColor(FXRGB(0, 0, 0));
935                 // enable save button
936                 myTAZFrameParent->myTAZSaveChanges->enableButtonsAndBeginUndoList();
937                 // update weight of all TAZSources
938                 for (const auto&  i : myEdgeAndTAZChildsSelected) {
939                     i.TAZSink->setAttribute(SUMO_ATTR_WEIGHT, myTextFieldTAZSinkWeight->getText().text(), myTAZFrameParent->myViewNet->getUndoList());
940                 }
941                 // refresh TAZ Edges
942                 myTAZFrameParent->getTAZCurrentModul()->refreshTAZEdges();
943             } else {
944                 // set invalid color
945                 myTextFieldTAZSinkWeight->setTextColor(FXRGB(255, 0, 0));
946             }
947         } else {
948             // set invalid color
949             myTextFieldTAZSinkWeight->setTextColor(FXRGB(255, 0, 0));
950         }
951     }
952     return 1;
953 }
954 
955 
956 long
onCmdSelectEdges(FXObject *,FXSelector,void *)957 GNETAZFrame::TAZSelectionStatistics::onCmdSelectEdges(FXObject*, FXSelector, void*) {
958     if (myEdgeAndTAZChildsSelected.size() == 0) {
959         // add to selection all TAZEdges
960         for (const auto& i : myTAZFrameParent->getTAZCurrentModul()->getTAZEdges()) {
961             // avoid empty undolists
962             if (!i.edge->isAttributeCarrierSelected()) {
963                 // enable save button
964                 myTAZFrameParent->myTAZSaveChanges->enableButtonsAndBeginUndoList();
965                 // change attribute selected
966                 i.edge->setAttribute(GNE_ATTR_SELECTED, "true", myTAZFrameParent->myViewNet->getUndoList());
967             }
968         }
969     } else {
970         // only add to selection selected TAZEdges
971         for (const auto& i : myEdgeAndTAZChildsSelected) {
972             // avoid empty undolists
973             if (!i.edge->isAttributeCarrierSelected()) {
974                 // enable save button
975                 myTAZFrameParent->myTAZSaveChanges->enableButtonsAndBeginUndoList();
976                 // change attribute selected
977                 i.edge->setAttribute(GNE_ATTR_SELECTED, "true", myTAZFrameParent->myViewNet->getUndoList());
978             }
979         }
980     }
981     // update view net
982     myTAZFrameParent->myViewNet->update();
983     return 1;
984 }
985 
986 
987 void
updateStatistics()988 GNETAZFrame::TAZSelectionStatistics::updateStatistics() {
989     if (myEdgeAndTAZChildsSelected.size() > 0) {
990         // show TAZSources/Sinks frames
991         myTAZSourceFrame->show();
992         myTAZSinkFrame->show();
993         // declare string sets for TextFields (to avoid duplicated values)
994         std::set<std::string> weightSourceSet;
995         std::set<std::string> weightSinkSet;
996         // declare stadistic variables
997         double weight = 0;
998         double maxWeightSource = 0;
999         double minWeightSource = -1;
1000         double averageWeightSource = 0;
1001         double maxWeightSink = 0;
1002         double minWeightSink = -1;
1003         double averageWeightSink = 0;
1004         // iterate over additional childs
1005         for (const auto&  i : myEdgeAndTAZChildsSelected) {
1006             //start with sources
1007             weight = i.TAZSource->getDepartWeight();
1008             // insert source weight in weightSinkTextField
1009             weightSourceSet.insert(toString(weight));
1010             // check max Weight
1011             if (maxWeightSource < weight) {
1012                 maxWeightSource = weight;
1013             }
1014             // check min Weight
1015             if (minWeightSource == -1 || (maxWeightSource < weight)) {
1016                 minWeightSource = weight;
1017             }
1018             // update Average
1019             averageWeightSource += weight;
1020             // continue with sinks
1021             weight = i.TAZSink->getDepartWeight();
1022             // save sink weight in weightSinkTextField
1023             weightSinkSet.insert(toString(weight));
1024             // check max Weight
1025             if (maxWeightSink < weight) {
1026                 maxWeightSink = weight;
1027             }
1028             // check min Weight
1029             if (minWeightSink == -1 || (maxWeightSink < weight)) {
1030                 minWeightSink = weight;
1031             }
1032             // update Average
1033             averageWeightSink += weight;
1034         }
1035         // calculate average
1036         averageWeightSource /= myEdgeAndTAZChildsSelected.size();
1037         averageWeightSink /= myEdgeAndTAZChildsSelected.size();
1038         // declare ostringstream for statistics
1039         std::ostringstream information;
1040         std::string edgeInformation;
1041         // first fill edgeInformation
1042         if (myEdgeAndTAZChildsSelected.size() == 1) {
1043             edgeInformation = "- Edge ID: " + myEdgeAndTAZChildsSelected.begin()->edge->getID();
1044         } else {
1045             edgeInformation = "- Number of edges: " + toString(myEdgeAndTAZChildsSelected.size());
1046         }
1047         // fill rest of information
1048         information
1049                 << edgeInformation << "\n"
1050                 << "- Min source: " << toString(minWeightSource) << "\n"
1051                 << "- Max source: " << toString(maxWeightSource) << "\n"
1052                 << "- Average source: " << toString(averageWeightSource) << "\n"
1053                 << "\n"
1054                 << "- Min sink: " << toString(minWeightSink) << "\n"
1055                 << "- Max sink: " << toString(maxWeightSink) << "\n"
1056                 << "- Average sink: " << toString(averageWeightSink);
1057         // set new label
1058         myStatisticsLabel->setText(information.str().c_str());
1059         // set TextFields (Text and color)
1060         myTextFieldTAZSourceWeight->setText(joinToString(weightSourceSet, " ").c_str());
1061         myTextFieldTAZSourceWeight->setTextColor(FXRGB(0, 0, 0));
1062         myTextFieldTAZSinkWeight->setText(joinToString(weightSinkSet, " ").c_str());
1063         myTextFieldTAZSinkWeight->setTextColor(FXRGB(0, 0, 0));
1064     } else {
1065         // hide TAZSources/Sinks frames
1066         myTAZSourceFrame->hide();
1067         myTAZSinkFrame->hide();
1068         // hide myStatisticsLabel
1069         myStatisticsLabel->setText("No edges selected");
1070     }
1071 }
1072 
1073 // ---------------------------------------------------------------------------
1074 // GNETAZFrame::TAZParameters- methods
1075 // ---------------------------------------------------------------------------
1076 
TAZParameters(GNETAZFrame * TAZFrameParent)1077 GNETAZFrame::TAZParameters::TAZParameters(GNETAZFrame* TAZFrameParent) :
1078     FXGroupBox(TAZFrameParent->myContentFrame, "TAZ parameters", GUIDesignGroupBoxFrame),
1079     myTAZFrameParent(TAZFrameParent) {
1080     // create Button and string textField for color and set blue as default color
1081     FXHorizontalFrame* colorParameter = new FXHorizontalFrame(this, GUIDesignAuxiliarHorizontalFrame);
1082     myColorEditor = new FXButton(colorParameter, toString(SUMO_ATTR_COLOR).c_str(), 0, this, MID_GNE_SET_ATTRIBUTE_DIALOG, GUIDesignButtonAttribute);
1083     myTextFieldColor = new FXTextField(colorParameter, GUIDesignTextFieldNCol, this, MID_GNE_SET_ATTRIBUTE, GUIDesignTextField);
1084     myTextFieldColor->setText("blue");
1085     // create Label and CheckButton for use innen edges with true as default value
1086     FXHorizontalFrame* useInnenEdges = new FXHorizontalFrame(this, GUIDesignAuxiliarHorizontalFrame);
1087     new FXLabel(useInnenEdges, "Edges within", 0, GUIDesignLabelAttribute);
1088     myAddEdgesWithinCheckButton = new FXCheckButton(useInnenEdges, "use", this, MID_GNE_SET_ATTRIBUTE, GUIDesignCheckButtonAttribute);
1089     myAddEdgesWithinCheckButton->setCheck(true);
1090     // Create help button
1091     myHelpTAZAttribute = new FXButton(this, "Help", 0, this, MID_HELP, GUIDesignButtonRectangular);
1092 }
1093 
1094 
~TAZParameters()1095 GNETAZFrame::TAZParameters::~TAZParameters() {}
1096 
1097 
1098 void
showTAZParametersModul()1099 GNETAZFrame::TAZParameters::showTAZParametersModul() {
1100     FXGroupBox::show();
1101 }
1102 
1103 
1104 void
hideTAZParametersModul()1105 GNETAZFrame::TAZParameters::hideTAZParametersModul() {
1106     FXGroupBox::hide();
1107 }
1108 
1109 
1110 bool
isCurrentParametersValid() const1111 GNETAZFrame::TAZParameters::isCurrentParametersValid() const {
1112     return GNEAttributeCarrier::canParse<RGBColor>(myTextFieldColor->getText().text());
1113 }
1114 
1115 
1116 bool
isAddEdgesWithinEnabled() const1117 GNETAZFrame::TAZParameters::isAddEdgesWithinEnabled() const {
1118     return (myAddEdgesWithinCheckButton->getCheck() == TRUE);
1119 }
1120 
1121 
1122 std::map<SumoXMLAttr, std::string>
getAttributesAndValues() const1123 GNETAZFrame::TAZParameters::getAttributesAndValues() const {
1124     std::map<SumoXMLAttr, std::string> parametersAndValues;
1125     // get color (currently the only editable attribute)
1126     parametersAndValues[SUMO_ATTR_COLOR] = myTextFieldColor->getText().text();
1127     return parametersAndValues;
1128 }
1129 
1130 
1131 long
onCmdSetColorAttribute(FXObject *,FXSelector,void *)1132 GNETAZFrame::TAZParameters::onCmdSetColorAttribute(FXObject*, FXSelector, void*) {
1133     // create FXColorDialog
1134     FXColorDialog colordialog(this, tr("Color Dialog"));
1135     colordialog.setTarget(this);
1136     // If previous attribute wasn't correct, set black as default color
1137     if (GNEAttributeCarrier::canParse<RGBColor>(myTextFieldColor->getText().text())) {
1138         colordialog.setRGBA(MFXUtils::getFXColor(RGBColor::parseColor(myTextFieldColor->getText().text())));
1139     } else {
1140         colordialog.setRGBA(MFXUtils::getFXColor(RGBColor::parseColor("blue")));
1141     }
1142     // execute dialog to get a new color
1143     if (colordialog.execute()) {
1144         myTextFieldColor->setText(toString(MFXUtils::getRGBColor(colordialog.getRGBA())).c_str());
1145         onCmdSetAttribute(0, 0, 0);
1146     }
1147     return 0;
1148 }
1149 
1150 
1151 long
onCmdSetAttribute(FXObject *,FXSelector,void *)1152 GNETAZFrame::TAZParameters::onCmdSetAttribute(FXObject*, FXSelector, void*) {
1153     // only COLOR text field has to be checked
1154     bool currentParametersValid = GNEAttributeCarrier::canParse<RGBColor>(myTextFieldColor->getText().text());
1155     // change color of textfield dependig of myCurrentParametersValid
1156     if (currentParametersValid) {
1157         myTextFieldColor->setTextColor(FXRGB(0, 0, 0));
1158         myTextFieldColor->killFocus();
1159     } else {
1160         myTextFieldColor->setTextColor(FXRGB(255, 0, 0));
1161         currentParametersValid = false;
1162     }
1163     // change useInnenEdgesCheckButton text
1164     if (myAddEdgesWithinCheckButton->getCheck() == TRUE) {
1165         myAddEdgesWithinCheckButton->setText("use");
1166     } else {
1167         myAddEdgesWithinCheckButton->setText("not use");
1168     }
1169     return 0;
1170 }
1171 
1172 
1173 long
onCmdHelp(FXObject *,FXSelector,void *)1174 GNETAZFrame::TAZParameters::onCmdHelp(FXObject*, FXSelector, void*) {
1175     myTAZFrameParent->openHelpAttributesDialog(GNEAttributeCarrier::getTagProperties(SUMO_TAG_TAZ));
1176     return 1;
1177 }
1178 
1179 // ---------------------------------------------------------------------------
1180 // GNETAZFrame::TAZEdgesGraphic - methods
1181 // ---------------------------------------------------------------------------
1182 
TAZEdgesGraphic(GNETAZFrame * TAZFrameParent)1183 GNETAZFrame::TAZEdgesGraphic::TAZEdgesGraphic(GNETAZFrame* TAZFrameParent) :
1184     FXGroupBox(TAZFrameParent->myContentFrame, "Edges", GUIDesignGroupBoxFrame),
1185     myTAZFrameParent(TAZFrameParent),
1186     myEdgeDefaultColor(RGBColor::GREY),
1187     myEdgeSelectedColor(RGBColor::MAGENTA) {
1188     // create label for non taz edge color information
1189     FXLabel* NonTAZEdgeLabel = new FXLabel(this, "Non TAZ Edge", nullptr, GUIDesignLabelCenter);
1190     NonTAZEdgeLabel->setBackColor(MFXUtils::getFXColor(myEdgeDefaultColor));
1191     NonTAZEdgeLabel->setTextColor(MFXUtils::getFXColor(RGBColor::WHITE));
1192     // create label for selected TAZEdge color information
1193     FXLabel* selectedTAZEdgeLabel = new FXLabel(this, "Selected TAZ Edge", nullptr, GUIDesignLabelCenter);
1194     selectedTAZEdgeLabel->setBackColor(MFXUtils::getFXColor(myEdgeSelectedColor));
1195     // create label for color information
1196     new FXLabel(this, "Scala: Min -> Max", nullptr, GUIDesignLabelCenterThick);
1197     // fill scale colors
1198     myScaleColors.push_back(RGBColor(232, 35,  0));
1199     myScaleColors.push_back(RGBColor(255, 165, 0));
1200     myScaleColors.push_back(RGBColor(255, 255, 0));
1201     myScaleColors.push_back(RGBColor(28,  215, 0));
1202     myScaleColors.push_back(RGBColor(0,   181, 100));
1203     myScaleColors.push_back(RGBColor(0,   255, 191));
1204     myScaleColors.push_back(RGBColor(178, 255, 255));
1205     myScaleColors.push_back(RGBColor(0,   112, 184));
1206     myScaleColors.push_back(RGBColor(56,  41,  131));
1207     myScaleColors.push_back(RGBColor(127, 0,   255));
1208     // create frame for color scale
1209     FXHorizontalFrame* horizontalFrameColors = new FXHorizontalFrame(this, GUIDesignAuxiliarHorizontalFrame);
1210     for (const auto& i : myScaleColors) {
1211         FXLabel* colorLabel = new FXLabel(horizontalFrameColors, "", nullptr, GUIDesignLabelLeft);
1212         colorLabel->setBackColor(MFXUtils::getFXColor(i));
1213     }
1214     // create Radio button for show edges by source weight
1215     myColorBySourceWeight = new FXRadioButton(this, "Color by Source", this, MID_CHOOSEN_OPERATION, GUIDesignRadioButton);
1216     // create Radio button for show edges by sink weight
1217     myColorBySinkWeight = new FXRadioButton(this, "Color by Sink", this, MID_CHOOSEN_OPERATION, GUIDesignRadioButton);
1218     // create Radio button for show edges by source + sink weight
1219     myColorBySourcePlusSinkWeight = new FXRadioButton(this, "Color by Source + Sink", this, MID_CHOOSEN_OPERATION, GUIDesignRadioButton);
1220     // create Radio button for show edges by source - sink weight
1221     myColorBySourceMinusSinkWeight = new FXRadioButton(this, "Color by Source - Sink", this, MID_CHOOSEN_OPERATION, GUIDesignRadioButton);
1222     // show by source as default
1223     myColorBySourceWeight->setCheck(true);
1224 }
1225 
1226 
~TAZEdgesGraphic()1227 GNETAZFrame::TAZEdgesGraphic::~TAZEdgesGraphic() {}
1228 
1229 
1230 void
showTAZEdgesGraphicModul()1231 GNETAZFrame::TAZEdgesGraphic::showTAZEdgesGraphicModul() {
1232     // update edge colors
1233     updateEdgeColors();
1234     show();
1235 }
1236 
1237 
1238 void
hideTAZEdgesGraphicModul()1239 GNETAZFrame::TAZEdgesGraphic::hideTAZEdgesGraphicModul() {
1240     // iterate over all edges and restore color
1241     for (const auto& i : myTAZFrameParent->myTAZCurrent->getNetEdges()) {
1242         for (const auto j : i->getLanes()) {
1243             j->setSpecialColor(nullptr);
1244         }
1245     }
1246     hide();
1247 }
1248 
1249 
1250 void
updateEdgeColors()1251 GNETAZFrame::TAZEdgesGraphic::updateEdgeColors() {
1252     // start painting all edges in gray
1253     for (const auto& i : myTAZFrameParent->myTAZCurrent->getNetEdges()) {
1254         // set candidate color (in this case, gray)
1255         for (const auto j : i->getLanes()) {
1256             j->setSpecialColor(&myEdgeDefaultColor);
1257         }
1258     }
1259     // now paint Source/sinks colors
1260     for (const auto& i : myTAZFrameParent->myTAZCurrent->getTAZEdges()) {
1261         // set candidate color (in this case,
1262         for (const auto j : i.edge->getLanes()) {
1263             // check what will be painted (source, sink or both)
1264             if (myColorBySourceWeight->getCheck() == TRUE) {
1265                 j->setSpecialColor(&myScaleColors.at(i.sourceColor), i.TAZSource->getDepartWeight());
1266             } else if (myColorBySinkWeight->getCheck() == TRUE) {
1267                 j->setSpecialColor(&myScaleColors.at(i.sinkColor), i.TAZSink->getDepartWeight());
1268             } else if (myColorBySourcePlusSinkWeight->getCheck() == TRUE) {
1269                 j->setSpecialColor(&myScaleColors.at(i.sourcePlusSinkColor), i.TAZSource->getDepartWeight() + i.TAZSink->getDepartWeight());
1270             } else {
1271                 j->setSpecialColor(&myScaleColors.at(i.sourceMinusSinkColor), i.TAZSource->getDepartWeight() - i.TAZSink->getDepartWeight());
1272             }
1273         }
1274     }
1275     // as last step paint candidate colors
1276     for (const auto& i : myTAZFrameParent->myTAZSelectionStatistics->getEdgeAndTAZChildsSelected()) {
1277         // set candidate selected color
1278         for (const auto& j : i.edge->getLanes()) {
1279             j->setSpecialColor(&myEdgeSelectedColor);
1280         }
1281     }
1282     // always update view after setting new colors
1283     myTAZFrameParent->myViewNet->update();
1284 }
1285 
1286 
1287 long
onCmdChoosenBy(FXObject * obj,FXSelector,void *)1288 GNETAZFrame::TAZEdgesGraphic::onCmdChoosenBy(FXObject* obj, FXSelector, void*) {
1289     // check what radio was pressed and disable the others
1290     if (obj == myColorBySourceWeight) {
1291         myColorBySinkWeight->setCheck(FALSE);
1292         myColorBySourcePlusSinkWeight->setCheck(FALSE);
1293         myColorBySourceMinusSinkWeight->setCheck(FALSE);
1294     } else if (obj == myColorBySinkWeight) {
1295         myColorBySourceWeight->setCheck(FALSE);
1296         myColorBySourcePlusSinkWeight->setCheck(FALSE);
1297         myColorBySourceMinusSinkWeight->setCheck(FALSE);
1298     } else if (obj == myColorBySourcePlusSinkWeight) {
1299         myColorBySourceWeight->setCheck(FALSE);
1300         myColorBySinkWeight->setCheck(FALSE);
1301         myColorBySourceMinusSinkWeight->setCheck(FALSE);
1302     } else if (obj == myColorBySourceMinusSinkWeight) {
1303         myColorBySourceWeight->setCheck(FALSE);
1304         myColorBySinkWeight->setCheck(FALSE);
1305         myColorBySourcePlusSinkWeight->setCheck(FALSE);
1306     }
1307     // update edge colors
1308     updateEdgeColors();
1309     return 1;
1310 }
1311 
1312 // ---------------------------------------------------------------------------
1313 // GNETAZFrame - methods
1314 // ---------------------------------------------------------------------------
1315 
GNETAZFrame(FXHorizontalFrame * horizontalFrameParent,GNEViewNet * viewNet)1316 GNETAZFrame::GNETAZFrame(FXHorizontalFrame* horizontalFrameParent, GNEViewNet* viewNet) :
1317     GNEFrame(horizontalFrameParent, viewNet, "TAZs") {
1318 
1319     // create current TAZ modul
1320     myTAZCurrent = new TAZCurrent(this);
1321 
1322     // Create TAZ Parameters modul
1323     myTAZParameters = new TAZParameters(this);
1324 
1325     /// @brief create  Netedit parameter
1326     myNeteditAttributes = new NeteditAttributes(this);
1327 
1328     // Create drawing controls modul
1329     myDrawingShape = new DrawingShape(this);
1330 
1331     // Create TAZ Edges Common Statistics modul
1332     myTAZCommonStatistics = new TAZCommonStatistics(this);
1333 
1334     // Create save TAZ Edges modul
1335     myTAZSaveChanges = new TAZSaveChanges(this);
1336 
1337     // Create TAZ Edges Common Parameters modul
1338     myTAZChildDefaultParameters = new TAZChildDefaultParameters(this);
1339 
1340     // Create TAZ Edges Selection Statistics modul
1341     myTAZSelectionStatistics = new TAZSelectionStatistics(this);
1342 
1343     // Create TAZ Edges Common Parameters modul
1344     myTAZEdgesGraphic = new TAZEdgesGraphic(this);
1345 
1346     // by default there isn't a TAZ
1347     myTAZCurrent->setTAZ(nullptr);
1348 }
1349 
1350 
~GNETAZFrame()1351 GNETAZFrame::~GNETAZFrame() {
1352 }
1353 
1354 
1355 void
hide()1356 GNETAZFrame::hide() {
1357     // hide frame
1358     GNEFrame::hide();
1359 }
1360 
1361 
1362 bool
processClick(const Position & clickedPosition,const GNEViewNetHelper::ObjectsUnderCursor & objectsUnderCursor)1363 GNETAZFrame::processClick(const Position& clickedPosition, const GNEViewNetHelper::ObjectsUnderCursor& objectsUnderCursor) {
1364     // Declare map to keep values
1365     std::map<SumoXMLAttr, std::string> valuesOfElement;
1366     if (myDrawingShape->isDrawing()) {
1367         // add or delete a new point depending of flag "delete last created point"
1368         if (myDrawingShape->getDeleteLastCreatedPoint()) {
1369             myDrawingShape->removeLastPoint();
1370         } else {
1371             myDrawingShape->addNewPoint(clickedPosition);
1372         }
1373         return true;
1374     } else if ((myTAZCurrent->getTAZ() == nullptr) || (objectsUnderCursor.getTAZFront() && myTAZCurrent->getTAZ() && !myTAZSaveChanges->isChangesPending())) {
1375         // if user click over an TAZ and there isn't changes pending, then select a new TAZ
1376         if (objectsUnderCursor.getTAZFront()) {
1377             // avoid reset of Frame if user doesn't click over an TAZ
1378             myTAZCurrent->setTAZ(objectsUnderCursor.getTAZFront());
1379             return true;
1380         } else {
1381             return false;
1382         }
1383     } else if (objectsUnderCursor.getEdgeFront()) {
1384         // if toogle Edge is enabled, select edge. In other case create two new TAZSource/Sinks
1385         if (myTAZChildDefaultParameters->getToggleMembership()) {
1386             // create new TAZSource/Sinks or delete it
1387             return addOrRemoveTAZMember(objectsUnderCursor.getEdgeFront());
1388         } else {
1389             // first check if clicked edge was previously selected
1390             if (myTAZSelectionStatistics->isEdgeSelected(objectsUnderCursor.getEdgeFront())) {
1391                 // clear selected edges
1392                 myTAZSelectionStatistics->clearSelectedEdges();
1393             } else {
1394                 // iterate over TAZEdges saved in TAZCurrent (it contains the Edge and Source/sinks)
1395                 for (const auto& i : myTAZCurrent->getTAZEdges()) {
1396                     if (i.edge == objectsUnderCursor.getEdgeFront()) {
1397                         // clear current selection (to avoid having two or more edges selected at the same time using mouse clicks)
1398                         myTAZSelectionStatistics->clearSelectedEdges();
1399                         // now select edge
1400                         myTAZSelectionStatistics->selectEdge(i);
1401                         // edge selected, then return true
1402                         return true;
1403                     }
1404                 }
1405             }
1406             // edge wasn't selected, then return false
1407             return false;
1408         }
1409     } else {
1410         // nothing to do
1411         return false;
1412     }
1413 }
1414 
1415 
1416 void
processEdgeSelection(const std::vector<GNEEdge * > & edges)1417 GNETAZFrame::processEdgeSelection(const std::vector<GNEEdge*>& edges) {
1418     // first check that a TAZ is selected
1419     if (myTAZCurrent->getTAZ()) {
1420         // if "toogle Membership" is enabled, create new TAZSources/sinks. In other case simply select edges
1421         if (myTAZChildDefaultParameters->getToggleMembership()) {
1422             // iterate over edges
1423             for (auto i : edges) {
1424                 // first check if edge owns a TAZEge
1425                 if (myTAZCurrent->isTAZEdge(i) == false) {
1426                     // create new TAZ Sources/Sinks
1427                     addOrRemoveTAZMember(i);
1428                 }
1429             }
1430         } else {
1431             // iterate over edges
1432             for (auto i : edges) {
1433                 // first check that selected edge isn't already selected
1434                 if (!myTAZSelectionStatistics->isEdgeSelected(i)) {
1435                     // iterate over TAZEdges saved in TAZCurrent (it contains the Edge and Source/sinks)
1436                     for (const auto& j : myTAZCurrent->getTAZEdges()) {
1437                         if (j.edge == i) {
1438                             myTAZSelectionStatistics->selectEdge(j);
1439                         }
1440                     }
1441                 }
1442             }
1443         }
1444     }
1445 }
1446 
1447 
1448 GNETAZFrame::DrawingShape*
getDrawingShapeModul() const1449 GNETAZFrame::getDrawingShapeModul() const {
1450     return myDrawingShape;
1451 }
1452 
1453 
1454 GNETAZFrame::TAZCurrent*
getTAZCurrentModul() const1455 GNETAZFrame::getTAZCurrentModul() const {
1456     return myTAZCurrent;
1457 }
1458 
1459 
1460 GNETAZFrame::TAZSelectionStatistics*
getTAZSelectionStatisticsModul() const1461 GNETAZFrame::getTAZSelectionStatisticsModul() const {
1462     return myTAZSelectionStatistics;
1463 }
1464 
1465 
1466 GNETAZFrame::TAZSaveChanges*
getTAZSaveChangesModul() const1467 GNETAZFrame::getTAZSaveChangesModul() const {
1468     return myTAZSaveChanges;
1469 }
1470 
1471 
1472 bool
buildShape()1473 GNETAZFrame::buildShape() {
1474     // show warning dialogbox and stop check if input parameters are valid
1475     if (!myTAZParameters->isCurrentParametersValid()) {
1476         return false;
1477     } else if (myDrawingShape->getTemporalShape().size() == 0) {
1478         WRITE_WARNING("TAZ shape cannot be empty");
1479         return false;
1480     } else {
1481         // Declare map to keep TAZ Parameters values
1482         std::map<SumoXMLAttr, std::string> valuesOfElement = myTAZParameters->getAttributesAndValues();
1483 
1484         // obtain Netedit attributes
1485         myNeteditAttributes->getNeteditAttributesAndValues(valuesOfElement, nullptr);
1486 
1487         // generate new ID
1488         valuesOfElement[SUMO_ATTR_ID] = myViewNet->getNet()->generateAdditionalID(SUMO_TAG_TAZ);
1489 
1490         // obtain shape and close it
1491         PositionVector shape = myDrawingShape->getTemporalShape();
1492         shape.closePolygon();
1493         valuesOfElement[SUMO_ATTR_SHAPE] = toString(shape);
1494 
1495         // check if TAZ has to be created with edges
1496         if (myTAZParameters->isAddEdgesWithinEnabled()) {
1497             std::vector<std::string> edgeIDs;
1498             auto ACsInBoundary = myViewNet->getAttributeCarriersInBoundary(shape.getBoxBoundary(), true);
1499             for (auto i : ACsInBoundary) {
1500                 if (i.second->getTagProperty().getTag() == SUMO_TAG_EDGE) {
1501                     edgeIDs.push_back(i.first);
1502                 }
1503             }
1504             valuesOfElement[SUMO_ATTR_EDGES] = toString(edgeIDs);
1505         } else {
1506             // TAZ is created without edges
1507             valuesOfElement[SUMO_ATTR_EDGES] = "";
1508         }
1509         // declare SUMOSAXAttributesImpl_Cached to convert valuesMap into SUMOSAXAttributes
1510         SUMOSAXAttributesImpl_Cached SUMOSAXAttrs(valuesOfElement, getPredefinedTagsMML(), toString(SUMO_TAG_TAZ));
1511         // return true if TAZ was successfully created
1512         return GNEAdditionalHandler::buildAdditional(myViewNet, true, SUMO_TAG_TAZ, SUMOSAXAttrs, nullptr);
1513     }
1514 }
1515 
1516 
1517 bool
addOrRemoveTAZMember(GNEEdge * edge)1518 GNETAZFrame::addOrRemoveTAZMember(GNEEdge* edge) {
1519     // first check if edge exist;
1520     if (edge) {
1521         // first check if already exist (in this case, remove it)
1522         for (const auto& i : myTAZCurrent->getTAZEdges()) {
1523             if (i.edge == edge) {
1524                 // enable save changes button
1525                 myTAZSaveChanges->enableButtonsAndBeginUndoList();
1526                 // remove Source and Sinks using GNEChange_Additional
1527                 myViewNet->getUndoList()->add(new GNEChange_Additional(i.TAZSource, false), true);
1528                 myViewNet->getUndoList()->add(new GNEChange_Additional(i.TAZSink, false), true);
1529                 // always refresh TAZ Edges after removing TAZSources/Sinks
1530                 myTAZCurrent->refreshTAZEdges();
1531                 // update select edges button
1532                 myTAZChildDefaultParameters->updateSelectEdgesButton();
1533                 return true;
1534             }
1535         }
1536         // if wasn't found, then add it
1537         myTAZSaveChanges->enableButtonsAndBeginUndoList();
1538         // create TAZ Sink using GNEChange_Additional and value of TAZChild default parameters
1539         GNETAZSourceSink* TAZSource = new GNETAZSourceSink(SUMO_TAG_TAZSOURCE, myTAZCurrent->getTAZ(), edge, myTAZChildDefaultParameters->getDefaultTAZSourceWeight());
1540         myViewNet->getUndoList()->add(new GNEChange_Additional(TAZSource, true), true);
1541         // create TAZ Sink using GNEChange_Additional and value of TAZChild default parameters
1542         GNETAZSourceSink* TAZSink = new GNETAZSourceSink(SUMO_TAG_TAZSINK, myTAZCurrent->getTAZ(), edge, myTAZChildDefaultParameters->getDefaultTAZSinkWeight());
1543         myViewNet->getUndoList()->add(new GNEChange_Additional(TAZSink, true), true);
1544         // always refresh TAZ Edges after adding TAZSources/Sinks
1545         myTAZCurrent->refreshTAZEdges();
1546         // update selected button
1547         myTAZChildDefaultParameters->updateSelectEdgesButton();
1548         return true;
1549     } else {
1550         throw ProcessError("Edge cannot be null");
1551     }
1552 }
1553 
1554 
1555 void
dropTAZMembers()1556 GNETAZFrame::dropTAZMembers() {
1557     // iterate over all TAZEdges
1558     for (const auto& i : myTAZCurrent->getTAZEdges()) {
1559         // enable save changes button
1560         myTAZSaveChanges->enableButtonsAndBeginUndoList();
1561         // remove Source and Sinks using GNEChange_Additional
1562         myViewNet->getUndoList()->add(new GNEChange_Additional(i.TAZSource, false), true);
1563         myViewNet->getUndoList()->add(new GNEChange_Additional(i.TAZSink, false), true);
1564     }
1565     // always refresh TAZ Edges after removing TAZSources/Sinks
1566     myTAZCurrent->refreshTAZEdges();
1567 }
1568 
1569 /****************************************************************************/
1570