Path: blob/main/src/netedit/frames/network/GNETAZFrame.cpp
169685 views
/****************************************************************************/1// Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.dev/sumo2// Copyright (C) 2001-2025 German Aerospace Center (DLR) and others.3// This program and the accompanying materials are made available under the4// terms of the Eclipse Public License 2.0 which is available at5// https://www.eclipse.org/legal/epl-2.0/6// This Source Code may also be made available under the following Secondary7// Licenses when the conditions for such availability set forth in the Eclipse8// Public License 2.0 are satisfied: GNU General Public License, version 29// or later which is available at10// https://www.gnu.org/licenses/old-licenses/gpl-2.0-standalone.html11// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later12/****************************************************************************/13/// @file GNETAZFrame.cpp14/// @author Pablo Alvarez Lopez15/// @date Oct 201816///17// The Widget for add TAZ elements18/****************************************************************************/1920#include <netedit/GNEApplicationWindow.h>21#include <netedit/GNENet.h>22#include <netedit/GNETagProperties.h>23#include <netedit/GNEUndoList.h>24#include <netedit/GNEViewParent.h>25#include <netedit/dialogs/basic/GNEQuestionBasicDialog.h>26#include <netedit/dialogs/basic/GNEInformationBasicDialog.h>27#include <netedit/changes/GNEChange_TAZSourceSink.h>28#include <netedit/elements/additional/GNEAdditionalHandler.h>29#include <netedit/elements/additional/GNETAZ.h>30#include <netedit/frames/GNEAttributesEditor.h>31#include <netedit/frames/GNEDrawingShape.h>32#include <utils/foxtools/MFXDynamicLabel.h>33#include <utils/gui/div/GUIDesigns.h>3435#include "GNETAZFrame.h"3637// ===========================================================================38// FOX callback mapping39// ===========================================================================4041FXDEFMAP(GNETAZFrame::TAZSaveChanges) TAZSaveChangesMap[] = {42FXMAPFUNC(SEL_COMMAND, MID_OK, GNETAZFrame::TAZSaveChanges::onCmdSaveChanges),43FXMAPFUNC(SEL_COMMAND, MID_CANCEL, GNETAZFrame::TAZSaveChanges::onCmdCancelChanges),44};4546FXDEFMAP(GNETAZFrame::TAZChildDefaultParameters) TAZChildDefaultParametersMap[] = {47FXMAPFUNC(SEL_COMMAND, MID_GNE_SET_ATTRIBUTE, GNETAZFrame::TAZChildDefaultParameters::onCmdSetDefaultValues),48FXMAPFUNC(SEL_COMMAND, MID_GNE_SELECT, GNETAZFrame::TAZChildDefaultParameters::onCmdUseSelectedEdges),49FXMAPFUNC(SEL_COMMAND, MID_GNE_SET_ZEROFRINGEPROB, GNETAZFrame::TAZChildDefaultParameters::onCmdSetZeroFringeProbabilities),50};5152FXDEFMAP(GNETAZFrame::TAZSelectionStatistics) TAZSelectionStatisticsMap[] = {53FXMAPFUNC(SEL_COMMAND, MID_GNE_SET_ATTRIBUTE, GNETAZFrame::TAZSelectionStatistics::onCmdSetNewValues),54};5556FXDEFMAP(GNETAZFrame::TAZEdgesGraphic) TAZEdgesGraphicMap[] = {57FXMAPFUNC(SEL_COMMAND, MID_CHOOSEN_OPERATION, GNETAZFrame::TAZEdgesGraphic::onCmdChoosenBy),58};5960// Object implementation61FXIMPLEMENT(GNETAZFrame::TAZSaveChanges, MFXGroupBoxModule, TAZSaveChangesMap, ARRAYNUMBER(TAZSaveChangesMap))62FXIMPLEMENT(GNETAZFrame::TAZChildDefaultParameters, MFXGroupBoxModule, TAZChildDefaultParametersMap, ARRAYNUMBER(TAZChildDefaultParametersMap))63FXIMPLEMENT(GNETAZFrame::TAZSelectionStatistics, MFXGroupBoxModule, TAZSelectionStatisticsMap, ARRAYNUMBER(TAZSelectionStatisticsMap))64FXIMPLEMENT(GNETAZFrame::TAZEdgesGraphic, MFXGroupBoxModule, TAZEdgesGraphicMap, ARRAYNUMBER(TAZEdgesGraphicMap))656667// ===========================================================================68// method definitions69// ===========================================================================7071// ---------------------------------------------------------------------------72// GNETAZFrame::CurrentTAZ - methods73// ---------------------------------------------------------------------------7475GNETAZFrame::CurrentTAZ::TAZEdgeColor::TAZEdgeColor(CurrentTAZ* CurrentTAZParent, GNEEdge* _edge, GNETAZSourceSink* _source, GNETAZSourceSink* _sink) :76edge(_edge),77source(_source),78sink(_sink),79sourceColor(0),80sinkColor(0),81sourcePlusSinkColor(0),82sourceMinusSinkColor(0),83myCurrentTAZParent(CurrentTAZParent) {84}858687GNETAZFrame::CurrentTAZ::TAZEdgeColor::~TAZEdgeColor() {}888990void91GNETAZFrame::CurrentTAZ::TAZEdgeColor::updateColors() {92sourceColor = source ? GNEAttributeCarrier::parse<int>(source->getAttribute(GNE_ATTR_TAZCOLOR)) : 0;93sinkColor = sink ? GNEAttributeCarrier::parse<int>(sink->getAttribute(GNE_ATTR_TAZCOLOR)) : 0;94double sourceWeight = source ? source->getWeight() : 0;95double sinkWeight = sink ? sink->getWeight() : 0;96// Obtain Source+Sink needs more steps. First obtain Source+Sink Weight97double sourcePlusSinkWeight = sourceWeight + sinkWeight;98// avoid division between zero99if ((myCurrentTAZParent->myMaxSourcePlusSinkWeight - myCurrentTAZParent->myMinSourcePlusSinkWeight) == 0) {100sourcePlusSinkColor = 0;101} else {102// calculate percentage relative to the max and min Source+Sink weight103double percentage = (sourcePlusSinkWeight - myCurrentTAZParent->myMinSourcePlusSinkWeight) /104(myCurrentTAZParent->myMaxSourcePlusSinkWeight - myCurrentTAZParent->myMinSourcePlusSinkWeight);105// convert percentage to a value between [0-9] (because we have only 10 colors)106if (percentage >= 1) {107sourcePlusSinkColor = 9;108} else if (percentage < 0) {109sourcePlusSinkColor = 0;110} else {111sourcePlusSinkColor = (int)(percentage * 10);112}113}114// Obtain Source+Sink needs more steps. First obtain Source-Sink Weight115double sourceMinusSinkWeight = sourceWeight - sinkWeight;116// avoid division between zero117if ((myCurrentTAZParent->myMaxSourceMinusSinkWeight - myCurrentTAZParent->myMinSourceMinusSinkWeight) == 0) {118sourceMinusSinkColor = 0;119} else {120// calculate percentage relative to the max and min Source-Sink weight121double percentage = (sourceMinusSinkWeight - myCurrentTAZParent->myMinSourceMinusSinkWeight) /122(myCurrentTAZParent->myMaxSourceMinusSinkWeight - myCurrentTAZParent->myMinSourceMinusSinkWeight);123// convert percentage to a value between [0-9] (because we have only 10 colors)124if (percentage >= 1) {125sourceMinusSinkColor = 9;126} else if (percentage < 0) {127sourceMinusSinkColor = 0;128} else {129sourceMinusSinkColor = (int)(percentage * 10);130}131}132}133134135GNETAZFrame::CurrentTAZ::TAZEdgeColor::TAZEdgeColor() :136edge(nullptr),137source(nullptr),138sink(nullptr),139sourceColor(0),140sinkColor(0),141sourcePlusSinkColor(0),142sourceMinusSinkColor(0),143myCurrentTAZParent(nullptr) {144}145146147GNETAZFrame::CurrentTAZ::CurrentTAZ(GNETAZFrame* TAZFrameParent) :148MFXGroupBoxModule(TAZFrameParent, TL("TAZ")),149myTAZFrameParent(TAZFrameParent),150myEditedTAZ(nullptr),151myMaxSourcePlusSinkWeight(0),152myMinSourcePlusSinkWeight(-1),153myMaxSourceMinusSinkWeight(0),154myMinSourceMinusSinkWeight(-1) {155// create TAZ label156myCurrentTAZLabel = new FXLabel(getCollapsableFrame(), TL("No TAZ selected"), 0, GUIDesignLabel(JUSTIFY_LEFT));157}158159160GNETAZFrame::CurrentTAZ::~CurrentTAZ() {}161162163void164GNETAZFrame::CurrentTAZ::setTAZ(GNETAZ* editedTAZ) {165// set new current TAZ166myEditedTAZ = editedTAZ;167// update label and moduls168if (myEditedTAZ != nullptr) {169myCurrentTAZLabel->setText((TL("Current TAZ: ") + myEditedTAZ->getID()).c_str());170// obtain a copy of all SELECTED edges of the net (to avoid slowdown during manipulations)171mySelectedEdges = myTAZFrameParent->myViewNet->getNet()->getAttributeCarriers()->getSelectedEdges();172// refresh TAZ Edges173refreshTAZEdges();174// hide TAZ parameters175myTAZFrameParent->myTAZAttributesEditor->hideAttributesEditor();176// hide drawing shape177myTAZFrameParent->myDrawingShape->hideDrawingShape();178// show edge common parameters179myTAZFrameParent->myTAZCommonStatistics->showTAZCommonStatisticsModule();180// show save TAZ Edges181myTAZFrameParent->myTAZSaveChanges->showTAZSaveChangesModule();182// show edge common parameters183myTAZFrameParent->myTAZChildDefaultParameters->extendTAZChildDefaultParameters();184// show Edges graphics185myTAZFrameParent->myTAZEdgesGraphic->showTAZEdgesGraphicModule();186} else {187// show TAZ parameters188myTAZFrameParent->myTAZAttributesEditor->showAttributesEditor(myTAZFrameParent->getViewNet()->getNet()->getACTemplates()->getTemplateAC(SUMO_TAG_TAZ), true);189// show drawing shape190myTAZFrameParent->myDrawingShape->showDrawingShape();191// hide edge common parameters192myTAZFrameParent->myTAZCommonStatistics->hideTAZCommonStatisticsModule();193// hide edge common parameters194myTAZFrameParent->myTAZChildDefaultParameters->collapseTAZChildDefaultParameters();195// hide Edges graphics196myTAZFrameParent->myTAZEdgesGraphic->hideTAZEdgesGraphicModule();197// hide save TAZ Edges198myTAZFrameParent->myTAZSaveChanges->hideTAZSaveChangesModule();199// restore label200myCurrentTAZLabel->setText(TL("No TAZ selected"));201// clear selected edges202mySelectedEdges.clear();203// reset all weight values204myMaxSourcePlusSinkWeight = 0;205myMinSourcePlusSinkWeight = -1;206myMaxSourceMinusSinkWeight = 0;207myMinSourceMinusSinkWeight = -1;208}209}210211212GNETAZ*213GNETAZFrame::CurrentTAZ::getTAZ() const {214return myEditedTAZ;215}216217218bool219GNETAZFrame::CurrentTAZ::isTAZEdge(GNEEdge* edge) const {220// simply iterate over edges and check edge parameter221for (const auto& TAZEdgeColor : myTAZEdgeColors) {222if (TAZEdgeColor.edge == edge) {223return true;224}225}226// not found, then return false227return false;228}229230231const std::vector<GNEEdge*>&232GNETAZFrame::CurrentTAZ::getSelectedEdges() const {233return mySelectedEdges;234}235236237const std::vector<GNETAZFrame::CurrentTAZ::TAZEdgeColor>&238GNETAZFrame::CurrentTAZ::getTAZEdges() const {239return myTAZEdgeColors;240}241242243void244GNETAZFrame::CurrentTAZ::refreshTAZEdges() {245// clear all curren TAZEdges246myTAZEdgeColors.clear();247// clear weight values248myMaxSourcePlusSinkWeight = 0;249myMinSourcePlusSinkWeight = -1;250myMaxSourceMinusSinkWeight = 0;251myMinSourceMinusSinkWeight = -1;252// only refresh if we're editing an TAZ253if (myEditedTAZ) {254// first update TAZ Statistics255myEditedTAZ->updateTAZStatistic();256myTAZFrameParent->myTAZCommonStatistics->updateStatistics();257// iterate over child TAZElements and create TAZEdges258for (const auto& TAZSourceSink : myEditedTAZ->getChildTAZSourceSinks()) {259addSourceSink(TAZSourceSink);260}261// update colors after add all edges262for (auto& TAZEdgeColor : myTAZEdgeColors) {263TAZEdgeColor.updateColors();264}265// update edge colors266myTAZFrameParent->myTAZEdgesGraphic->updateEdgeColors();267}268}269270271void272GNETAZFrame::CurrentTAZ::addSourceSink(GNETAZSourceSink* sourceSink) {273GNEEdge* edge = myTAZFrameParent->myViewNet->getNet()->getAttributeCarriers()->retrieveEdge(sourceSink->getAttribute(SUMO_ATTR_EDGE));274// first check if TAZEdgeColor has to be created275bool createTAZEdge = true;276for (auto& TAZEdgeColor : myTAZEdgeColors) {277if (TAZEdgeColor.edge == edge) {278createTAZEdge = false;279// update TAZ Source or Sink280if (sourceSink->getTagProperty()->getTag() == SUMO_TAG_TAZSOURCE) {281TAZEdgeColor.source = sourceSink;282} else {283TAZEdgeColor.sink = sourceSink;284}285}286}287// check if TAZElements has to be created288if (createTAZEdge) {289if (sourceSink->getTagProperty()->getTag() == SUMO_TAG_TAZSOURCE) {290myTAZEdgeColors.push_back(TAZEdgeColor(this, edge, sourceSink, nullptr));291} else {292myTAZEdgeColors.push_back(TAZEdgeColor(this, edge, nullptr, sourceSink));293}294}295// recalculate weights296myMaxSourcePlusSinkWeight = 0;297myMinSourcePlusSinkWeight = -1;298myMaxSourceMinusSinkWeight = 0;299myMinSourceMinusSinkWeight = -1;300for (const auto& TAZEdgeColor : myTAZEdgeColors) {301// make sure that both TAZ Source and Sink exist302if (TAZEdgeColor.source && TAZEdgeColor.sink) {303// obtain source plus sink304double sourcePlusSink = TAZEdgeColor.source->getWeight() + TAZEdgeColor.sink->getWeight();305// check myMaxSourcePlusSinkWeight306if (sourcePlusSink > myMaxSourcePlusSinkWeight) {307myMaxSourcePlusSinkWeight = sourcePlusSink;308}309// check myMinSourcePlusSinkWeight310if ((myMinSourcePlusSinkWeight == -1) || (sourcePlusSink < myMinSourcePlusSinkWeight)) {311myMinSourcePlusSinkWeight = sourcePlusSink;312}313// obtain source minus sink314double sourceMinusSink = TAZEdgeColor.source->getWeight() - TAZEdgeColor.sink->getWeight();315// use valor absolute316if (sourceMinusSink < 0) {317sourceMinusSink *= -1;318}319// check myMaxSourcePlusSinkWeight320if (sourceMinusSink > myMaxSourceMinusSinkWeight) {321myMaxSourceMinusSinkWeight = sourceMinusSink;322}323// check myMinSourcePlusSinkWeight324if ((myMinSourceMinusSinkWeight == -1) || (sourceMinusSink < myMinSourceMinusSinkWeight)) {325myMinSourceMinusSinkWeight = sourceMinusSink;326}327}328}329}330331// ---------------------------------------------------------------------------332// GNETAZFrame::TAZCommonStatistics - methods333// ---------------------------------------------------------------------------334335GNETAZFrame::TAZCommonStatistics::TAZCommonStatistics(GNETAZFrame* TAZFrameParent) :336MFXGroupBoxModule(TAZFrameParent, TL("TAZ Statistics")),337myTAZFrameParent(TAZFrameParent) {338// create label for statistics339myStatisticsLabel = new FXLabel(getCollapsableFrame(), TL("Statistics"), 0, GUIDesignLabelFrameInformation);340}341342343GNETAZFrame::TAZCommonStatistics::~TAZCommonStatistics() {}344345346void347GNETAZFrame::TAZCommonStatistics::showTAZCommonStatisticsModule() {348// always update statistics after show349updateStatistics();350show();351}352353354void355GNETAZFrame::TAZCommonStatistics::hideTAZCommonStatisticsModule() {356hide();357}358359360void361GNETAZFrame::TAZCommonStatistics::updateStatistics() {362if (myTAZFrameParent->myCurrentTAZ->getTAZ()) {363// declare ostringstream for statistics364std::ostringstream information;365information366<< TL("- Number of edges: ") << toString(myTAZFrameParent->myCurrentTAZ->getTAZ()->getChildTAZSourceSinks().size() / 2) << "\n"367<< TL("- Min source: ") << myTAZFrameParent->myCurrentTAZ->getTAZ()->getAttribute(GNE_ATTR_MIN_SOURCE) << "\n"368<< TL("- Max source: ") << myTAZFrameParent->myCurrentTAZ->getTAZ()->getAttribute(GNE_ATTR_MAX_SOURCE) << "\n"369<< TL("- Average source: ") << myTAZFrameParent->myCurrentTAZ->getTAZ()->getAttribute(GNE_ATTR_AVERAGE_SOURCE) << "\n"370<< "\n"371<< TL("- Min sink: ") << myTAZFrameParent->myCurrentTAZ->getTAZ()->getAttribute(GNE_ATTR_MIN_SINK) << "\n"372<< TL("- Max sink: ") << myTAZFrameParent->myCurrentTAZ->getTAZ()->getAttribute(GNE_ATTR_MAX_SINK) << "\n"373<< TL("- Average sink: ") << myTAZFrameParent->myCurrentTAZ->getTAZ()->getAttribute(GNE_ATTR_AVERAGE_SINK);374// set new label375myStatisticsLabel->setText(information.str().c_str());376} else {377myStatisticsLabel->setText(TL("No TAZ Selected"));378}379}380381// ---------------------------------------------------------------------------382// GNETAZFrame::TAZSaveChanges - methods383// ---------------------------------------------------------------------------384385GNETAZFrame::TAZSaveChanges::TAZSaveChanges(GNETAZFrame* TAZFrameParent) :386MFXGroupBoxModule(TAZFrameParent, TL("Modifications")),387myTAZFrameParent(TAZFrameParent) {388// Create groupbox for save changes389mySaveChangesButton = GUIDesigns::buildFXButton(getCollapsableFrame(), TL("Confirm changes"), "", "", GUIIconSubSys::getIcon(GUIIcon::SAVE), this, MID_OK, GUIDesignButton);390mySaveChangesButton->disable();391// Create groupbox cancel changes392myCancelChangesButton = GUIDesigns::buildFXButton(getCollapsableFrame(), TL("Cancel changes"), "", "", GUIIconSubSys::getIcon(GUIIcon::CANCEL), this, MID_CANCEL, GUIDesignButton);393myCancelChangesButton->disable();394}395396397GNETAZFrame::TAZSaveChanges::~TAZSaveChanges() {}398399400void401GNETAZFrame::TAZSaveChanges::showTAZSaveChangesModule() {402show();403}404405406void407GNETAZFrame::TAZSaveChanges::hideTAZSaveChangesModule() {408// cancel changes before hiding module409onCmdCancelChanges(0, 0, 0);410hide();411}412413414void415GNETAZFrame::TAZSaveChanges::enableButtonsAndBeginUndoList() {416// check that save changes is disabled417if (!mySaveChangesButton->isEnabled()) {418// enable mySaveChangesButton and myCancelChangesButton419mySaveChangesButton->enable();420myCancelChangesButton->enable();421// start undo list set422myTAZFrameParent->myViewNet->getUndoList()->begin(GUIIcon::TAZ, TL("TAZ changes"));423}424}425426427bool428GNETAZFrame::TAZSaveChanges::isChangesPending() const {429// simply check if save Changes Button is enabled430return myTAZFrameParent->shown() && mySaveChangesButton->isEnabled();431}432433434long435GNETAZFrame::TAZSaveChanges::onCmdSaveChanges(FXObject*, FXSelector, void*) {436// check that save changes is enabled437if (mySaveChangesButton->isEnabled()) {438// disable mySaveChangesButton and myCancelChangesButton439mySaveChangesButton->disable();440myCancelChangesButton->disable();441// finish undo list set442myTAZFrameParent->myViewNet->getUndoList()->end();443// always refresh TAZ Edges after removing TAZSources/Sinks444myTAZFrameParent->myCurrentTAZ->refreshTAZEdges();445// update use edges button446myTAZFrameParent->myTAZChildDefaultParameters->updateSelectEdgesButton();447448}449return 1;450}451452453long454GNETAZFrame::TAZSaveChanges::onCmdCancelChanges(FXObject*, FXSelector, void*) {455// check that save changes is enabled456if (mySaveChangesButton->isEnabled()) {457// disable buttons458mySaveChangesButton->disable();459myCancelChangesButton->disable();460// abort undo list461myTAZFrameParent->myViewNet->getUndoList()->abortAllChangeGroups();462// always refresh TAZ Edges after removing TAZSources/Sinks463myTAZFrameParent->myCurrentTAZ->refreshTAZEdges();464// update use edges button465myTAZFrameParent->myTAZChildDefaultParameters->updateSelectEdgesButton();466}467return 1;468}469470// ---------------------------------------------------------------------------471// GNETAZFrame::TAZChildDefaultParameters - methods472// ---------------------------------------------------------------------------473474GNETAZFrame::TAZChildDefaultParameters::TAZChildDefaultParameters(GNETAZFrame* TAZFrameParent) :475MFXGroupBoxModule(TAZFrameParent, TL("TAZ Sources/Sinks")),476myTAZFrameParent(TAZFrameParent),477myDefaultTAZSourceWeight(1),478myDefaultTAZSinkWeight(1) {479// create checkbox for toggle membership480myToggleMembershipFrame = new FXHorizontalFrame(getCollapsableFrame(), GUIDesignAuxiliarHorizontalFrame);481new FXLabel(myToggleMembershipFrame, TL("Membership"), 0, GUIDesignLabelThickedFixed(100));482myToggleMembership = new FXCheckButton(myToggleMembershipFrame, TL("Toggle"), this, MID_GNE_SET_ATTRIBUTE, GUIDesignCheckButton);483// by default enabled484myToggleMembership->setCheck(TRUE);485// create default TAZ Source weight486myDefaultTAZSourceFrame = new FXHorizontalFrame(getCollapsableFrame(), GUIDesignAuxiliarHorizontalFrame);487new FXLabel(myDefaultTAZSourceFrame, TL("New source"), 0, GUIDesignLabelThickedFixed(100));488myTextFieldDefaultValueTAZSources = new FXTextField(myDefaultTAZSourceFrame, GUIDesignTextFieldNCol, this, MID_GNE_SET_ATTRIBUTE, GUIDesignTextField);489myTextFieldDefaultValueTAZSources->setText("1");490// create default TAZ Sink weight491myDefaultTAZSinkFrame = new FXHorizontalFrame(getCollapsableFrame(), GUIDesignAuxiliarHorizontalFrame);492new FXLabel(myDefaultTAZSinkFrame, TL("New sink"), 0, GUIDesignLabelThickedFixed(100));493myTextFieldDefaultValueTAZSinks = new FXTextField(myDefaultTAZSinkFrame, GUIDesignTextFieldNCol, this, MID_GNE_SET_ATTRIBUTE, GUIDesignTextField);494myTextFieldDefaultValueTAZSinks->setText("1");495// Create button for use selected edges496myUseSelectedEdges = GUIDesigns::buildFXButton(getCollapsableFrame(), TL("Use selected edges"), "", "", nullptr, this, MID_GNE_SELECT, GUIDesignButton);497// Create button for zero fringe probabilities498myZeroFringeProbabilities = GUIDesigns::buildFXButton(getCollapsableFrame(), TL("Set zero fringe prob."), "", "", nullptr, this, MID_GNE_SET_ZEROFRINGEPROB, GUIDesignButton);499// Create information label500std::ostringstream information;501information502<< std::string("- ") << TL("Toggle Membership:") << "\n"503<< std::string(" ") << TL("Create new Sources/Sinks with given weights.");504myInformationLabel = new MFXDynamicLabel(getCollapsableFrame(), information.str().c_str(), 0, GUIDesignLabelFrameInformation);505// always show506show();507}508509510GNETAZFrame::TAZChildDefaultParameters::~TAZChildDefaultParameters() {}511512513void514GNETAZFrame::TAZChildDefaultParameters::extendTAZChildDefaultParameters() {515// check if TAZ selection Statistics Module has to be shown516if (myToggleMembership->getCheck() == FALSE) {517myTAZFrameParent->myTAZSelectionStatistics->showTAZSelectionStatisticsModule();518} else {519myTAZFrameParent->myTAZSelectionStatistics->hideTAZSelectionStatisticsModule();520}521// update selected button522updateSelectEdgesButton();523// show items edges button524myToggleMembershipFrame->show();525myDefaultTAZSourceFrame->show();526myDefaultTAZSinkFrame->show();527myUseSelectedEdges->show();528myInformationLabel->show();529}530531532void533GNETAZFrame::TAZChildDefaultParameters::collapseTAZChildDefaultParameters() {534// hide TAZ Selection Statistics Module535myTAZFrameParent->myTAZSelectionStatistics->hideTAZSelectionStatisticsModule();536// hide items537myToggleMembershipFrame->hide();538myDefaultTAZSourceFrame->hide();539myDefaultTAZSinkFrame->hide();540myUseSelectedEdges->hide();541myInformationLabel->hide();542}543544545void546GNETAZFrame::TAZChildDefaultParameters::updateSelectEdgesButton() {547if (myToggleMembership->getCheck() == TRUE) {548// check if use selected edges has to be enabled549if (myTAZFrameParent->myCurrentTAZ->getSelectedEdges().size() > 0) {550myUseSelectedEdges->setText(TL("Use selected edges"));551myUseSelectedEdges->enable();552} else if (myTAZFrameParent->myCurrentTAZ->getTAZEdges().size() > 0) {553myUseSelectedEdges->setText(TL("Remove all edges"));554myUseSelectedEdges->enable();555} else {556myUseSelectedEdges->setText(TL("Use selected edges"));557myUseSelectedEdges->disable();558}559} else if (myTAZFrameParent->getCurrentTAZModule()->getTAZEdges().size() > 0) {560// enable myUseSelectedEdges button561myUseSelectedEdges->enable();562// update mySelectEdgesOfSelection label563if (myTAZFrameParent->myTAZSelectionStatistics->getEdgeAndTAZChildrenSelected().size() == 0) {564// check if all edges of TAZChildren are selected565bool allSelected = true;566for (const auto& TAZEdgeColor : myTAZFrameParent->getCurrentTAZModule()->getTAZEdges()) {567if (!TAZEdgeColor.edge->isAttributeCarrierSelected()) {568allSelected = false;569}570}571if (allSelected) {572myUseSelectedEdges->setText(TL("Remove all edges from selection"));573} else {574myUseSelectedEdges->setText(TL("Add all edges to selection"));575}576} else if (myTAZFrameParent->myTAZSelectionStatistics->getEdgeAndTAZChildrenSelected().size() == 1) {577if (myTAZFrameParent->myTAZSelectionStatistics->getEdgeAndTAZChildrenSelected().front().edge->isAttributeCarrierSelected()) {578myUseSelectedEdges->setText(TL("Remove edge from selection"));579} else {580myUseSelectedEdges->setText(TL("Add edge to selection"));581}582} else {583// check if all edges of TAZChildren selected are selected584bool allSelected = true;585for (const auto& selectedEdge : myTAZFrameParent->myTAZSelectionStatistics->getEdgeAndTAZChildrenSelected()) {586if (!selectedEdge.edge->isAttributeCarrierSelected()) {587allSelected = false;588}589}590if (allSelected) {591myUseSelectedEdges->setText((TL("Remove ") + toString(myTAZFrameParent->myTAZSelectionStatistics->getEdgeAndTAZChildrenSelected().size()) + TL(" edges from to selection")).c_str());592} else {593myUseSelectedEdges->setText((TL("Add ") + toString(myTAZFrameParent->myTAZSelectionStatistics->getEdgeAndTAZChildrenSelected().size()) + TL(" edges to selection")).c_str());594}595}596} else {597// TAZ doesn't have children, then disable button598myUseSelectedEdges->disable();599}600}601602603double604GNETAZFrame::TAZChildDefaultParameters::getDefaultTAZSourceWeight() const {605return myDefaultTAZSourceWeight;606}607608609double610GNETAZFrame::TAZChildDefaultParameters::getDefaultTAZSinkWeight() const {611return myDefaultTAZSinkWeight;612}613614615bool616GNETAZFrame::TAZChildDefaultParameters::getToggleMembership() const {617return (myToggleMembership->getCheck() == TRUE);618}619620621long622GNETAZFrame::TAZChildDefaultParameters::onCmdSetDefaultValues(FXObject* obj, FXSelector, void*) {623// find edited object624if (obj == myToggleMembership) {625// first clear selected edges626myTAZFrameParent->myTAZSelectionStatistics->clearSelectedEdges();627// set text of myToggleMembership628if (myToggleMembership->getCheck() == TRUE) {629myToggleMembership->setText(TL("toggle"));630// show source/Sink Frames631myDefaultTAZSourceFrame->show();632myDefaultTAZSinkFrame->show();633// update information label634std::ostringstream information;635information636<< std::string("- ") << TL("Toggle Membership:") << "\n"637<< std::string(" ") << TL("Create new Sources/Sinks with given weights.");638myInformationLabel->setText(information.str().c_str());639// hide TAZSelectionStatistics640myTAZFrameParent->myTAZSelectionStatistics->hideTAZSelectionStatisticsModule();641// check if use selected edges has to be enabled642if (myTAZFrameParent->myCurrentTAZ->getSelectedEdges().size() > 0) {643myUseSelectedEdges->setText(TL("Use selected edges"));644} else if (myTAZFrameParent->myCurrentTAZ->getTAZEdges().size() > 0) {645myUseSelectedEdges->setText(TL("Remove all edges"));646} else {647myUseSelectedEdges->setText(TL("Use selected edges"));648myUseSelectedEdges->disable();649}650} else {651myToggleMembership->setText(TL("keep"));652// hide source/Sink Frames653myDefaultTAZSourceFrame->hide();654myDefaultTAZSinkFrame->hide();655// update information label656std::ostringstream information;657information658<< std::string("- ") << TL("Keep Membership:") << TL(" Select Sources/Sinks.") << "\n"659<< std::string("- ") << TL("Press ESC to clear the current selection.");660myInformationLabel->setText(information.str().c_str());661// show TAZSelectionStatistics662myTAZFrameParent->myTAZSelectionStatistics->showTAZSelectionStatisticsModule();663}664// update button665updateSelectEdgesButton();666} else if (obj == myTextFieldDefaultValueTAZSources) {667// check if given value is valid668if (GNEAttributeCarrier::canParse<double>(myTextFieldDefaultValueTAZSources->getText().text())) {669myDefaultTAZSourceWeight = GNEAttributeCarrier::parse<double>(myTextFieldDefaultValueTAZSources->getText().text());670// check if myDefaultTAZSourceWeight is greater than 0671if (myDefaultTAZSourceWeight >= 0) {672// set valid color673myTextFieldDefaultValueTAZSources->setTextColor(GUIDesignTextColorBlack);674} else {675// set invalid color676myTextFieldDefaultValueTAZSources->setTextColor(GUIDesignTextColorRed);677myDefaultTAZSourceWeight = 1;678}679} else {680// set invalid color681myTextFieldDefaultValueTAZSources->setTextColor(GUIDesignTextColorRed);682myDefaultTAZSourceWeight = 1;683}684} else if (obj == myTextFieldDefaultValueTAZSinks) {685// check if given value is valid686if (GNEAttributeCarrier::canParse<double>(myTextFieldDefaultValueTAZSinks->getText().text())) {687myDefaultTAZSinkWeight = GNEAttributeCarrier::parse<double>(myTextFieldDefaultValueTAZSinks->getText().text());688// check if myDefaultTAZSinkWeight is greater than 0689if (myDefaultTAZSinkWeight >= 0) {690// set valid color691myTextFieldDefaultValueTAZSinks->setTextColor(GUIDesignTextColorBlack);692} else {693// set invalid color694myTextFieldDefaultValueTAZSinks->setTextColor(GUIDesignTextColorRed);695myDefaultTAZSinkWeight = 1;696}697} else {698// set invalid color699myTextFieldDefaultValueTAZSinks->setTextColor(GUIDesignTextColorRed);700myDefaultTAZSinkWeight = 1;701}702}703return 1;704}705706707long708GNETAZFrame::TAZChildDefaultParameters::onCmdUseSelectedEdges(FXObject*, FXSelector, void*) {709// select edge or create new TAZ Source/Child, depending of myToggleMembership710if (myToggleMembership->getCheck() == TRUE) {711// first drop all edges712myTAZFrameParent->dropTAZMembers();713// iterate over selected edges and add it as TAZMember714for (const auto& selectedEdge : myTAZFrameParent->myCurrentTAZ->getSelectedEdges()) {715myTAZFrameParent->addOrRemoveTAZMember(selectedEdge);716}717// update selected button718updateSelectEdgesButton();719} else {720if (myTAZFrameParent->myTAZSelectionStatistics->getEdgeAndTAZChildrenSelected().size() == 0) {721// first check if all TAZEdges are selected722bool allSelected = true;723for (const auto& TAZEdgeColor : myTAZFrameParent->getCurrentTAZModule()->getTAZEdges()) {724if (!TAZEdgeColor.edge->isAttributeCarrierSelected()) {725allSelected = false;726}727}728// select or unselect all depending of allSelected729if (allSelected) {730// remove form selection all TAZEdges731for (const auto& TAZEdgeColor : myTAZFrameParent->getCurrentTAZModule()->getTAZEdges()) {732// change attribute selected (without undo-redo)733TAZEdgeColor.edge->unselectAttributeCarrier();734}735} else {736// add to selection all TAZEdges737for (const auto& TAZEdgeColor : myTAZFrameParent->getCurrentTAZModule()->getTAZEdges()) {738// change attribute selected (without undo-redo)739TAZEdgeColor.edge->selectAttributeCarrier();740}741}742} else {743// first check if all TAZEdges are selected744bool allSelected = true;745for (const auto& selectedEdge : myTAZFrameParent->myTAZSelectionStatistics->getEdgeAndTAZChildrenSelected()) {746if (!selectedEdge.edge->isAttributeCarrierSelected()) {747allSelected = false;748}749}750// select or unselect all depending of allSelected751if (allSelected) {752// only remove from selection selected TAZEdges753for (const auto& selectedEdge : myTAZFrameParent->myTAZSelectionStatistics->getEdgeAndTAZChildrenSelected()) {754if (selectedEdge.edge->isAttributeCarrierSelected()) {755// change attribute selected (without undo-redo)756selectedEdge.edge->unselectAttributeCarrier();757}758}759} else {760// only add to selection selected TAZEdges761for (const auto& selectedEdge : myTAZFrameParent->myTAZSelectionStatistics->getEdgeAndTAZChildrenSelected()) {762if (!selectedEdge.edge->isAttributeCarrierSelected()) {763// change attribute selected (without undo-redo)764selectedEdge.edge->selectAttributeCarrier();765}766}767}768}769}770// update selection button771myTAZFrameParent->myTAZChildDefaultParameters->updateSelectEdgesButton();772// update view net773myTAZFrameParent->myViewNet->updateViewNet();774return 1;775}776777778long779GNETAZFrame::TAZChildDefaultParameters::onCmdSetZeroFringeProbabilities(FXObject*, FXSelector, void*) {780// compute and update781auto& neteditOptions = OptionsCont::getOptions();782myTAZFrameParent->getViewNet()->getNet()->computeAndUpdate(neteditOptions, false);783myTAZFrameParent->getViewNet()->update();784// find all edges with TAZSource/sinks and without successors/predecessors785std::vector<GNETAZSourceSink*> sources;786std::vector<GNETAZSourceSink*> sinks;787std::set<GNEAdditional*> TAZs;788// check if we're editing a single TAZ or all TAZs789if (myTAZFrameParent->myCurrentTAZ->getTAZ() != nullptr) {790// iterate over source/sinks791for (const auto& TAZSourceSink : myTAZFrameParent->myCurrentTAZ->getTAZ()->getChildTAZSourceSinks()) {792if (TAZSourceSink->getTagProperty()->getTag() == SUMO_TAG_TAZSOURCE) {793// set sink probability to 0 for all edges that have no predecessor794if (!TAZSourceSink->getParentEdges().front()->hasSuccessors() &&795(TAZSourceSink->getAttributeDouble(SUMO_ATTR_WEIGHT) != 0)) {796sources.push_back(TAZSourceSink);797TAZs.insert(myTAZFrameParent->myCurrentTAZ->getTAZ());798}799} else {800// set source probability to 0 for all edges that have no successor801if (!TAZSourceSink->getParentEdges().front()->hasPredecessors() &&802(TAZSourceSink->getAttributeDouble(SUMO_ATTR_WEIGHT) != 0)) {803sinks.push_back(TAZSourceSink);804TAZs.insert(myTAZFrameParent->myCurrentTAZ->getTAZ());805}806}807}808} else {809// iterate over all TAZs810for (const auto& TAZ : myTAZFrameParent->getViewNet()->getNet()->getAttributeCarriers()->getAdditionals().at(SUMO_TAG_TAZ)) {811// iterate over source/sinks812for (const auto& TAZSourceSink : TAZ.second->getChildTAZSourceSinks()) {813if (TAZSourceSink->getTagProperty()->getTag() == SUMO_TAG_TAZSOURCE) {814// set sink probability to 0 for all edges that have no predecessor815if (!TAZSourceSink->getParentEdges().front()->hasSuccessors() &&816(TAZSourceSink->getAttributeDouble(SUMO_ATTR_WEIGHT) != 0)) {817sources.push_back(TAZSourceSink);818TAZs.insert(TAZ.second);819}820} else {821// set source probability to 0 for all edges that have no successor822if (!TAZSourceSink->getParentEdges().front()->hasPredecessors() &&823(TAZSourceSink->getAttributeDouble(SUMO_ATTR_WEIGHT) != 0)) {824sinks.push_back(TAZSourceSink);825TAZs.insert(TAZ.second);826}827}828}829}830}831// check if there is sources/sinks832if ((sources.size() + sinks.size()) > 0) {833// build the text834const std::string text = (TAZs.size() == 1) ?835// single TAZ836TL("Set weight 0 in ") + toString(sources.size()) + TL(" sources and ") +837toString(sinks.size()) + TL(" sinks from TAZ '") + (*TAZs.begin())->getID() + "'?" :838// multiple TAZs839TL("Set weight 0 in ") + toString(sources.size()) + TL(" sources and ") +840toString(sinks.size()) + TL(" sinks from ") + toString(TAZs.size()) + TL(" TAZs?");841// open question dialog842const auto questionDialog = GNEQuestionBasicDialog(myTAZFrameParent->getViewNet()->getViewParent()->getGNEAppWindows(),843GNEDialog::Buttons::YES_NO, TL("Set zero fringe probabilities"), text);844// continue depending of answer845if (questionDialog.getResult() == GNEDialog::Result::ACCEPT) {846myTAZFrameParent->myViewNet->getUndoList()->begin(GUIIcon::TAZ, TL("set zero fringe probabilities"));847for (const auto& source : sources) {848source->setAttribute(SUMO_ATTR_WEIGHT, "0", myTAZFrameParent->myViewNet->getUndoList());849}850for (const auto& sink : sinks) {851sink->setAttribute(SUMO_ATTR_WEIGHT, "0", myTAZFrameParent->myViewNet->getUndoList());852}853myTAZFrameParent->myViewNet->getUndoList()->end();854}855} else {856// show information box857GNEInformationBasicDialog(myTAZFrameParent->getViewNet()->getViewParent()->getGNEAppWindows(),858TL("Set zero fringe probabilities"), TL("No source/sinks to update."));859}860return 1;861}862863// ---------------------------------------------------------------------------864// GNETAZFrame::TAZSelectionStatistics - methods865// ---------------------------------------------------------------------------866867GNETAZFrame::TAZSelectionStatistics::TAZSelectionStatistics(GNETAZFrame* TAZFrameParent) :868MFXGroupBoxModule(TAZFrameParent, TL("Selection Statistics")),869myTAZFrameParent(TAZFrameParent) {870// create default TAZ Source weight871myTAZSourceFrame = new FXHorizontalFrame(getCollapsableFrame(), GUIDesignAuxiliarHorizontalFrame);872new FXLabel(myTAZSourceFrame, TL("Source"), 0, GUIDesignLabelThickedFixed(100));873myTextFieldTAZSourceWeight = new FXTextField(myTAZSourceFrame, GUIDesignTextFieldNCol, this, MID_GNE_SET_ATTRIBUTE, GUIDesignTextField);874myTAZSourceFrame->hide();875// create default TAZ Sink weight876myTAZSinkFrame = new FXHorizontalFrame(getCollapsableFrame(), GUIDesignAuxiliarHorizontalFrame);877new FXLabel(myTAZSinkFrame, TL("Sink"), 0, GUIDesignLabelThickedFixed(100));878myTextFieldTAZSinkWeight = new FXTextField(myTAZSinkFrame, GUIDesignTextFieldNCol, this, MID_GNE_SET_ATTRIBUTE, GUIDesignTextField);879myTAZSinkFrame->hide();880// create label for statistics881myStatisticsLabel = new FXLabel(getCollapsableFrame(), TL("Statistics"), 0, GUIDesignLabelFrameInformation);882}883884885GNETAZFrame::TAZSelectionStatistics::~TAZSelectionStatistics() {}886887888void889GNETAZFrame::TAZSelectionStatistics::showTAZSelectionStatisticsModule() {890// update Statistics before show891updateStatistics();892show();893}894895896void897GNETAZFrame::TAZSelectionStatistics::hideTAZSelectionStatisticsModule() {898// clear children before hide899clearSelectedEdges();900hide();901}902903904bool905GNETAZFrame::TAZSelectionStatistics::selectEdge(const CurrentTAZ::TAZEdgeColor& TAZEdgeColor) {906// find TAZEdgeColor using edge as criterium wasn't previously selected907for (const auto& selectedEdge : myEdgeAndTAZChildrenSelected) {908if (selectedEdge.edge == TAZEdgeColor.edge) {909throw ProcessError(TL("TAZEdgeColor already selected"));910}911}912// add edge and their TAZ Children into myTAZChildSelected913myEdgeAndTAZChildrenSelected.push_back(TAZEdgeColor);914// always update statistics after insertion915updateStatistics();916// update edge colors917myTAZFrameParent->myTAZEdgesGraphic->updateEdgeColors();918// update selection button919myTAZFrameParent->myTAZChildDefaultParameters->updateSelectEdgesButton();920return true;921}922923924bool925GNETAZFrame::TAZSelectionStatistics::unselectEdge(GNEEdge* edge) {926if (edge) {927// find TAZEdgeColor using edge as criterium928for (auto it = myEdgeAndTAZChildrenSelected.begin(); it != myEdgeAndTAZChildrenSelected.end(); it++) {929if (it->edge == edge) {930myEdgeAndTAZChildrenSelected.erase(it);931// always update statistics after insertion932updateStatistics();933// update edge colors934myTAZFrameParent->myTAZEdgesGraphic->updateEdgeColors();935// update selection button936myTAZFrameParent->myTAZChildDefaultParameters->updateSelectEdgesButton();937return true;938}939}940// throw exception if edge wasn't found941throw ProcessError(TL("edge wasn't found"));942} else {943throw ProcessError(TL("Invalid edge"));944}945}946947948bool949GNETAZFrame::TAZSelectionStatistics::isEdgeSelected(GNEEdge* edge) {950// find TAZEdgeColor using edge as criterium951for (const auto& selectedEdge : myEdgeAndTAZChildrenSelected) {952if (selectedEdge.edge == edge) {953return true;954}955}956// edge wasn't found, then return false957return false;958}959960961void962GNETAZFrame::TAZSelectionStatistics::clearSelectedEdges() {963// clear all selected edges (and the TAZ Children)964myEdgeAndTAZChildrenSelected.clear();965// always update statistics after clear edges966updateStatistics();967// update edge colors968myTAZFrameParent->myTAZEdgesGraphic->updateEdgeColors();969// update selection button970myTAZFrameParent->myTAZChildDefaultParameters->updateSelectEdgesButton();971}972973974const std::vector<GNETAZFrame::CurrentTAZ::TAZEdgeColor>&975GNETAZFrame::TAZSelectionStatistics::getEdgeAndTAZChildrenSelected() const {976return myEdgeAndTAZChildrenSelected;977}978979980long981GNETAZFrame::TAZSelectionStatistics::onCmdSetNewValues(FXObject* obj, FXSelector, void*) {982if (obj == myTextFieldTAZSourceWeight) {983// check if given value is valid984if (GNEAttributeCarrier::canParse<double>(myTextFieldTAZSourceWeight->getText().text())) {985double newTAZSourceWeight = GNEAttributeCarrier::parse<double>(myTextFieldTAZSourceWeight->getText().text());986// check if myDefaultTAZSourceWeight is greater than 0987if (newTAZSourceWeight >= 0) {988// set valid color in TextField989myTextFieldTAZSourceWeight->setTextColor(GUIDesignTextColorBlack);990// enable save button991myTAZFrameParent->myTAZSaveChanges->enableButtonsAndBeginUndoList();992// update weight of all TAZSources993for (const auto& selectedEdge : myEdgeAndTAZChildrenSelected) {994selectedEdge.source->setAttribute(SUMO_ATTR_WEIGHT, myTextFieldTAZSourceWeight->getText().text(), myTAZFrameParent->myViewNet->getUndoList());995}996// refresh TAZ Edges997myTAZFrameParent->getCurrentTAZModule()->refreshTAZEdges();998} else {999// set invalid color1000myTextFieldTAZSourceWeight->setTextColor(GUIDesignTextColorRed);1001}1002} else {1003// set invalid color1004myTextFieldTAZSourceWeight->setTextColor(GUIDesignTextColorRed);1005}1006} else if (obj == myTextFieldTAZSinkWeight) {1007// check if given value is valid1008if (GNEAttributeCarrier::canParse<double>(myTextFieldTAZSinkWeight->getText().text())) {1009double newTAZSinkWeight = GNEAttributeCarrier::parse<double>(myTextFieldTAZSinkWeight->getText().text());1010// check if myDefaultTAZSinkWeight is greater than 01011if (newTAZSinkWeight >= 0) {1012// set valid color in TextField1013myTextFieldTAZSinkWeight->setTextColor(GUIDesignTextColorBlack);1014// enable save button1015myTAZFrameParent->myTAZSaveChanges->enableButtonsAndBeginUndoList();1016// update weight of all TAZSources1017for (const auto& selectedEdge : myEdgeAndTAZChildrenSelected) {1018selectedEdge.sink->setAttribute(SUMO_ATTR_WEIGHT, myTextFieldTAZSinkWeight->getText().text(), myTAZFrameParent->myViewNet->getUndoList());1019}1020// refresh TAZ Edges1021myTAZFrameParent->getCurrentTAZModule()->refreshTAZEdges();1022} else {1023// set invalid color1024myTextFieldTAZSinkWeight->setTextColor(GUIDesignTextColorRed);1025}1026} else {1027// set invalid color1028myTextFieldTAZSinkWeight->setTextColor(GUIDesignTextColorRed);1029}1030}1031return 1;1032}103310341035long1036GNETAZFrame::TAZSelectionStatistics::onCmdSelectEdges(FXObject*, FXSelector, void*) {1037if (myEdgeAndTAZChildrenSelected.size() == 0) {1038// add to selection all TAZEdges1039for (const auto& TAZEdgeColor : myTAZFrameParent->getCurrentTAZModule()->getTAZEdges()) {1040// avoid empty undolists1041if (!TAZEdgeColor.edge->isAttributeCarrierSelected()) {1042// enable save button1043myTAZFrameParent->myTAZSaveChanges->enableButtonsAndBeginUndoList();1044// change attribute selected1045TAZEdgeColor.edge->setAttribute(GNE_ATTR_SELECTED, "true", myTAZFrameParent->myViewNet->getUndoList());1046}1047}1048} else {1049// only add to selection selected TAZEdges1050for (const auto& selectedEdge : myEdgeAndTAZChildrenSelected) {1051// avoid empty undolists1052if (!selectedEdge.edge->isAttributeCarrierSelected()) {1053// enable save button1054myTAZFrameParent->myTAZSaveChanges->enableButtonsAndBeginUndoList();1055// change attribute selected1056selectedEdge.edge->setAttribute(GNE_ATTR_SELECTED, "true", myTAZFrameParent->myViewNet->getUndoList());1057}1058}1059}1060return 1;1061}106210631064void1065GNETAZFrame::TAZSelectionStatistics::updateStatistics() {1066if (myEdgeAndTAZChildrenSelected.size() > 0) {1067// show TAZSources/Sinks frames1068myTAZSourceFrame->show();1069myTAZSinkFrame->show();1070// declare string sets for TextFields (to avoid duplicated values)1071std::set<std::string> weightSourceSet;1072std::set<std::string> weightSinkSet;1073// declare statistic variables1074double weight = 0;1075double maxWeightSource = 0;1076double minWeightSource = -1;1077double averageWeightSource = 0;1078double maxWeightSink = 0;1079double minWeightSink = -1;1080double averageWeightSink = 0;1081// iterate over child TAZElements1082for (const auto& selectedEdge : myEdgeAndTAZChildrenSelected) {1083//start with sources1084weight = selectedEdge.source->getWeight();1085// insert source weight in weightSinkTextField1086weightSourceSet.insert(toString(weight));1087// check max Weight1088if (maxWeightSource < weight) {1089maxWeightSource = weight;1090}1091// check min Weight1092if (minWeightSource == -1 || (maxWeightSource < weight)) {1093minWeightSource = weight;1094}1095// update Average1096averageWeightSource += weight;1097// continue with sinks1098weight = selectedEdge.sink->getWeight();1099// save sink weight in weightSinkTextField1100weightSinkSet.insert(toString(weight));1101// check max Weight1102if (maxWeightSink < weight) {1103maxWeightSink = weight;1104}1105// check min Weight1106if (minWeightSink == -1 || (maxWeightSink < weight)) {1107minWeightSink = weight;1108}1109// update Average1110averageWeightSink += weight;1111}1112// calculate average1113averageWeightSource /= (double)myEdgeAndTAZChildrenSelected.size();1114averageWeightSink /= (double)myEdgeAndTAZChildrenSelected.size();1115// declare ostringstream for statistics1116std::ostringstream information;1117std::string edgeInformation;1118// first fill edgeInformation1119if (myEdgeAndTAZChildrenSelected.size() == 1) {1120edgeInformation = TL("- Edge ID: ") + myEdgeAndTAZChildrenSelected.begin()->edge->getID();1121} else {1122edgeInformation = TL("- Number of edges: ") + toString(myEdgeAndTAZChildrenSelected.size());1123}1124// fill rest of information1125information1126<< edgeInformation << "\n"1127<< TL("- Min source: ") << toString(minWeightSource) << "\n"1128<< TL("- Max source: ") << toString(maxWeightSource) << "\n"1129<< TL("- Average source: ") << toString(averageWeightSource) << "\n"1130<< "\n"1131<< TL("- Min sink: ") << toString(minWeightSink) << "\n"1132<< TL("- Max sink: ") << toString(maxWeightSink) << "\n"1133<< TL("- Average sink: ") << toString(averageWeightSink);1134// set new label1135myStatisticsLabel->setText(information.str().c_str());1136// set TextFields (Text and color)1137myTextFieldTAZSourceWeight->setText(joinToString(weightSourceSet, " ").c_str());1138myTextFieldTAZSourceWeight->setTextColor(GUIDesignTextColorBlack);1139myTextFieldTAZSinkWeight->setText(joinToString(weightSinkSet, " ").c_str());1140myTextFieldTAZSinkWeight->setTextColor(GUIDesignTextColorBlack);1141} else {1142// hide TAZSources/Sinks frames1143myTAZSourceFrame->hide();1144myTAZSinkFrame->hide();1145// hide myStatisticsLabel1146myStatisticsLabel->setText(TL("No edges selected"));1147}1148}11491150// ---------------------------------------------------------------------------1151// GNETAZFrame::TAZEdgesGraphic - methods1152// ---------------------------------------------------------------------------11531154GNETAZFrame::TAZEdgesGraphic::TAZEdgesGraphic(GNETAZFrame* TAZFrameParent) :1155MFXGroupBoxModule(TAZFrameParent, TL("Edges")),1156myTAZFrameParent(TAZFrameParent),1157myEdgeDefaultColor(RGBColor::GREY),1158myEdgeSelectedColor(RGBColor::MAGENTA) {1159// create label for non taz edge color information1160FXLabel* NonTAZEdgeLabel = new FXLabel(getCollapsableFrame(), TL("Non TAZ Edge"), nullptr, GUIDesignLabel(JUSTIFY_NORMAL));1161NonTAZEdgeLabel->setBackColor(MFXUtils::getFXColor(myEdgeDefaultColor));1162NonTAZEdgeLabel->setTextColor(MFXUtils::getFXColor(RGBColor::WHITE));1163// create label for selected TAZEdgeColor color information1164FXLabel* selectedTAZEdgeLabel = new FXLabel(getCollapsableFrame(), TL("Selected TAZ Edge"), nullptr, GUIDesignLabel(JUSTIFY_NORMAL));1165selectedTAZEdgeLabel->setBackColor(MFXUtils::getFXColor(myEdgeSelectedColor));1166// build rainbow1167GNEFrame::buildRainbow(this);1168// create Radio button for show edges by source weight1169myColorBySourceWeight = new FXRadioButton(getCollapsableFrame(), TL("Color by Source"), this, MID_CHOOSEN_OPERATION, GUIDesignRadioButton);1170// create Radio button for show edges by sink weight1171myColorBySinkWeight = new FXRadioButton(getCollapsableFrame(), TL("Color by Sink"), this, MID_CHOOSEN_OPERATION, GUIDesignRadioButton);1172// create Radio button for show edges by source + sink weight1173myColorBySourcePlusSinkWeight = new FXRadioButton(getCollapsableFrame(), TL("Color by Source + Sink"), this, MID_CHOOSEN_OPERATION, GUIDesignRadioButton);1174// create Radio button for show edges by source - sink weight1175myColorBySourceMinusSinkWeight = new FXRadioButton(getCollapsableFrame(), TL("Color by Source - Sink"), this, MID_CHOOSEN_OPERATION, GUIDesignRadioButton);1176// show by source as default1177myColorBySourceWeight->setCheck(true);1178}117911801181GNETAZFrame::TAZEdgesGraphic::~TAZEdgesGraphic() {}118211831184void1185GNETAZFrame::TAZEdgesGraphic::showTAZEdgesGraphicModule() {1186// update edge colors1187updateEdgeColors();1188show();1189}119011911192void1193GNETAZFrame::TAZEdgesGraphic::hideTAZEdgesGraphicModule() {1194// iterate over all edges and restore color1195for (const auto& edge : myTAZFrameParent->getViewNet()->getNet()->getAttributeCarriers()->getEdges()) {1196for (const auto& lane : edge.second->getChildLanes()) {1197lane->setSpecialColor(nullptr);1198}1199}1200hide();1201}120212031204void1205GNETAZFrame::TAZEdgesGraphic::updateEdgeColors() {1206const std::vector<RGBColor>& scaledColors = GNEViewNetHelper::getRainbowScaledColors();1207// start painting all edges in gray1208for (const auto& edge : myTAZFrameParent->getViewNet()->getNet()->getAttributeCarriers()->getEdges()) {1209if (!edge.second->isAttributeCarrierSelected()) {1210// set candidate color (in this case, gray)1211for (const auto lane : edge.second->getChildLanes()) {1212lane->setSpecialColor(&myEdgeDefaultColor);1213}1214}1215}1216// now paint Source/sinks colors1217for (const auto& TAZEdgeColor : myTAZFrameParent->myCurrentTAZ->getTAZEdges()) {1218if (!TAZEdgeColor.edge->isAttributeCarrierSelected()) {1219// set candidate color (in this case,1220for (const auto& lane : TAZEdgeColor.edge->getChildLanes()) {1221// check what will be painted (source, sink or both)1222if (myColorBySourceWeight->getCheck() == TRUE) {1223lane->setSpecialColor(&scaledColors.at(TAZEdgeColor.sourceColor), TAZEdgeColor.source->getWeight());1224} else if (myColorBySinkWeight->getCheck() == TRUE) {1225lane->setSpecialColor(&scaledColors.at(TAZEdgeColor.sinkColor), TAZEdgeColor.sink->getWeight());1226} else if (myColorBySourcePlusSinkWeight->getCheck() == TRUE) {1227lane->setSpecialColor(&scaledColors.at(TAZEdgeColor.sourcePlusSinkColor), TAZEdgeColor.source->getWeight() + TAZEdgeColor.sink->getWeight());1228} else {1229lane->setSpecialColor(&scaledColors.at(TAZEdgeColor.sourceMinusSinkColor), TAZEdgeColor.source->getWeight() - TAZEdgeColor.sink->getWeight());1230}1231}1232}1233}1234// as last step paint candidate colors1235for (const auto& selectedEdge : myTAZFrameParent->myTAZSelectionStatistics->getEdgeAndTAZChildrenSelected()) {1236if (!selectedEdge.edge->isAttributeCarrierSelected()) {1237// set candidate selected color1238for (const auto& lane : selectedEdge.edge->getChildLanes()) {1239lane->setSpecialColor(&myEdgeSelectedColor);1240}1241}1242}1243// always update view after setting new colors1244myTAZFrameParent->myViewNet->updateViewNet();1245}124612471248long1249GNETAZFrame::TAZEdgesGraphic::onCmdChoosenBy(FXObject* obj, FXSelector, void*) {1250// check what radio was pressed and disable the others1251if (obj == myColorBySourceWeight) {1252myColorBySinkWeight->setCheck(FALSE);1253myColorBySourcePlusSinkWeight->setCheck(FALSE);1254myColorBySourceMinusSinkWeight->setCheck(FALSE);1255} else if (obj == myColorBySinkWeight) {1256myColorBySourceWeight->setCheck(FALSE);1257myColorBySourcePlusSinkWeight->setCheck(FALSE);1258myColorBySourceMinusSinkWeight->setCheck(FALSE);1259} else if (obj == myColorBySourcePlusSinkWeight) {1260myColorBySourceWeight->setCheck(FALSE);1261myColorBySinkWeight->setCheck(FALSE);1262myColorBySourceMinusSinkWeight->setCheck(FALSE);1263} else if (obj == myColorBySourceMinusSinkWeight) {1264myColorBySourceWeight->setCheck(FALSE);1265myColorBySinkWeight->setCheck(FALSE);1266myColorBySourcePlusSinkWeight->setCheck(FALSE);1267}1268// update edge colors1269updateEdgeColors();1270return 1;1271}12721273// ---------------------------------------------------------------------------1274// GNETAZFrame - methods1275// ---------------------------------------------------------------------------12761277GNETAZFrame::GNETAZFrame(GNEViewParent* viewParent, GNEViewNet* viewNet) :1278GNEFrame(viewParent, viewNet, TL("TAZs")) {12791280// create current TAZ module1281myCurrentTAZ = new CurrentTAZ(this);12821283// Create TAZ Parameters module1284myTAZAttributesEditor = new GNEAttributesEditor(this, GNEAttributesEditorType::EditorType::CREATOR);12851286// Create drawing controls module1287myDrawingShape = new GNEDrawingShape(this);12881289// Create TAZ Edges Common Statistics module1290myTAZCommonStatistics = new TAZCommonStatistics(this);12911292// Create save TAZ Edges module1293myTAZSaveChanges = new TAZSaveChanges(this);12941295// Create TAZ Edges Common Parameters module1296myTAZChildDefaultParameters = new TAZChildDefaultParameters(this);12971298// Create TAZ Edges Selection Statistics module1299myTAZSelectionStatistics = new TAZSelectionStatistics(this);13001301// Create TAZ Edges Common Parameters module1302myTAZEdgesGraphic = new TAZEdgesGraphic(this);13031304// by default there isn't a TAZ1305myCurrentTAZ->setTAZ(nullptr);1306}130713081309GNETAZFrame::~GNETAZFrame() {1310// check if we have to delete base TAZ object1311if (myBaseTAZ) {1312delete myBaseTAZ;1313}1314}131513161317void1318GNETAZFrame::show() {1319// edit template1320myCurrentTAZ->setTAZ(nullptr);1321// show frame1322GNEFrame::show();1323}132413251326void1327GNETAZFrame::hide() {1328// hide frame1329GNEFrame::hide();1330}133113321333bool1334GNETAZFrame::processClick(const Position& clickedPosition, const GNEViewNetHelper::ViewObjectsSelector& viewObjects) {1335// Declare map to keep values1336std::map<SumoXMLAttr, std::string> valuesOfElement;1337if (myDrawingShape->isDrawing()) {1338// add or delete a new point depending of flag "delete last created point"1339if (myDrawingShape->getDeleteLastCreatedPoint()) {1340myDrawingShape->removeLastPoint();1341} else {1342myDrawingShape->addNewPoint(clickedPosition);1343}1344return true;1345} else if ((myCurrentTAZ->getTAZ() == nullptr) || (viewObjects.getTAZFront() && myCurrentTAZ->getTAZ() && !myTAZSaveChanges->isChangesPending())) {1346// if user click over an TAZ and there isn't changes pending, then select a new TAZ1347if (viewObjects.getTAZFront()) {1348// avoid reset of Frame if user doesn't click over an TAZ1349myCurrentTAZ->setTAZ(viewObjects.getTAZFront());1350// update TAZStatistics1351myCurrentTAZ->getTAZ()->updateTAZStatistic();1352myTAZCommonStatistics->updateStatistics();1353return true;1354} else {1355return false;1356}1357} else if (viewObjects.getEdgeFront()) {1358// if toggle Edge is enabled, select edge. In other case create two new source/Sinks1359if (myTAZChildDefaultParameters->getToggleMembership()) {1360// create new source/Sinks or delete it1361return addOrRemoveTAZMember(viewObjects.getEdgeFront());1362} else {1363// first check if clicked edge was previously selected1364if (myTAZSelectionStatistics->isEdgeSelected(viewObjects.getEdgeFront())) {1365// clear selected edges1366myTAZSelectionStatistics->clearSelectedEdges();1367} else {1368// iterate over TAZEdges saved in CurrentTAZ (it contains the Edge and Source/sinks)1369for (const auto& TAZEdgeColor : myCurrentTAZ->getTAZEdges()) {1370if (TAZEdgeColor.edge == viewObjects.getEdgeFront()) {1371// clear current selection (to avoid having two or more edges selected at the same time using mouse clicks)1372myTAZSelectionStatistics->clearSelectedEdges();1373// now select edge1374myTAZSelectionStatistics->selectEdge(TAZEdgeColor);1375// edge selected, then return true1376return true;1377}1378}1379}1380// edge wasn't selected, then return false1381return false;1382}1383} else {1384// nothing to do1385return false;1386}1387}138813891390void1391GNETAZFrame::processEdgeSelection(const std::vector<GNEEdge*>& edges) {1392// first check that a TAZ is selected1393if (myCurrentTAZ->getTAZ()) {1394// if "toggle Membership" is enabled, create new TAZSources/sinks. In other case simply select edges1395if (myTAZChildDefaultParameters->getToggleMembership()) {1396// iterate over edges1397for (const auto& edge : edges) {1398// first check if edge owns a TAZEge1399if (!myCurrentTAZ->isTAZEdge(edge)) {1400// create new TAZ Sources/Sinks1401addOrRemoveTAZMember(edge);1402}1403}1404} else {1405// iterate over edges1406for (const auto& edge : edges) {1407// first check that selected edge isn't already selected1408if (!myTAZSelectionStatistics->isEdgeSelected(edge)) {1409// iterate over TAZEdges saved in CurrentTAZ (it contains the Edge and Source/sinks)1410for (const auto& TAZEdgeColor : myCurrentTAZ->getTAZEdges()) {1411if (TAZEdgeColor.edge == edge) {1412myTAZSelectionStatistics->selectEdge(TAZEdgeColor);1413}1414}1415}1416}1417}1418}1419}142014211422GNEDrawingShape*1423GNETAZFrame::getDrawingShapeModule() const {1424return myDrawingShape;1425}142614271428GNETAZFrame::CurrentTAZ*1429GNETAZFrame::getCurrentTAZModule() const {1430return myCurrentTAZ;1431}143214331434GNETAZFrame::TAZSelectionStatistics*1435GNETAZFrame::getTAZSelectionStatisticsModule() const {1436return myTAZSelectionStatistics;1437}143814391440GNETAZFrame::TAZSaveChanges*1441GNETAZFrame::getTAZSaveChangesModule() const {1442return myTAZSaveChanges;1443}144414451446bool1447GNETAZFrame::shapeDrawed() {1448// show warning dialogbox and stop check if input parameters are valid1449if (!myTAZAttributesEditor->checkAttributes(true)) {1450return false;1451} else if (myDrawingShape->getTemporalShape().size() < 3) {1452WRITE_WARNING(TL("TAZ shape needs at least three points"));1453return false;1454} else {1455// reset base TAZ element1456if (myBaseTAZ) {1457delete myBaseTAZ;1458}1459// create an new base additional1460myBaseTAZ = new CommonXMLStructure::SumoBaseObject(nullptr);1461myBaseTAZ->setTag(SUMO_TAG_TAZ);1462// get attributes and values1463myTAZAttributesEditor->fillSumoBaseObject(myBaseTAZ);1464// generate new ID1465myBaseTAZ->addStringAttribute(SUMO_ATTR_ID, myViewNet->getNet()->getAttributeCarriers()->generateAdditionalID(SUMO_TAG_TAZ));1466// obtain shape and close it1467PositionVector shape = myDrawingShape->getTemporalShape();1468shape.closePolygon();1469myBaseTAZ->addPositionVectorAttribute(SUMO_ATTR_SHAPE, shape);1470// set center if is invalid1471if (myBaseTAZ->getPositionAttribute(SUMO_ATTR_CENTER) == Position::INVALID) {1472myBaseTAZ->addPositionAttribute(SUMO_ATTR_CENTER, shape.getCentroid());1473}1474// check if TAZ has to be created with edges1475if (myBaseTAZ->getBoolAttribute(GNE_ATTR_EDGES_WITHIN)) {1476// get all elements within shape1477myViewNet->updateObjectsInShape(shape);1478// declare edge IDs1479std::vector<std::string> edgeIDs;1480edgeIDs.reserve(myViewNet->getViewObjectsSelector().getEdges().size());1481// get only edges with geometry around triangle1482for (const auto& edge : myViewNet->getViewObjectsSelector().getEdges()) {1483edgeIDs.push_back(edge->getID());1484}1485myBaseTAZ->addStringListAttribute(SUMO_ATTR_EDGES, edgeIDs);1486} else {1487// TAZ is created without edges1488myBaseTAZ->addStringListAttribute(SUMO_ATTR_EDGES, std::vector<std::string>());1489}1490// declare additional handler1491GNEAdditionalHandler additionalHandler(myViewNet->getNet(), myBaseTAZ->hasStringAttribute(GNE_ATTR_ADDITIONAL_FILE) ?1492myBaseTAZ->getStringAttribute(GNE_ATTR_ADDITIONAL_FILE) : "",1493myViewNet->getViewParent()->getGNEAppWindows()->isUndoRedoAllowed());1494// build TAZ1495additionalHandler.parseSumoBaseObject(myBaseTAZ);1496// Write info1497WRITE_MESSAGE(TLF("Created % sources and sinks", (2 * myBaseTAZ->getStringListAttribute(SUMO_ATTR_EDGES).size())));1498// TAZ created, then return true1499return true;1500}1501}150215031504bool1505GNETAZFrame::addOrRemoveTAZMember(GNEEdge* edge) {1506// first check if edge exist;1507if (edge) {1508// first check if already exist (in this case, remove it)1509for (const auto& TAZEdgeColor : myCurrentTAZ->getTAZEdges()) {1510if (TAZEdgeColor.edge == edge) {1511// enable save changes button1512myTAZSaveChanges->enableButtonsAndBeginUndoList();1513// remove Source and Sinks using GNEChange_TAZElement1514if (myViewNet->getNet()->getAttributeCarriers()->retrieveAdditional(TAZEdgeColor.source->getGUIGlObject(), false)) {1515myViewNet->getUndoList()->add(new GNEChange_TAZSourceSink(TAZEdgeColor.source, false), true);1516}1517if (myViewNet->getNet()->getAttributeCarriers()->retrieveAdditional(TAZEdgeColor.sink->getGUIGlObject(), false)) {1518myViewNet->getUndoList()->add(new GNEChange_TAZSourceSink(TAZEdgeColor.sink, false), true);1519}1520// always refresh TAZ Edges after removing TAZSources/Sinks1521myCurrentTAZ->refreshTAZEdges();1522// update select edges button1523myTAZChildDefaultParameters->updateSelectEdgesButton();1524return true;1525}1526}1527// if wasn't found, then add it1528myTAZSaveChanges->enableButtonsAndBeginUndoList();1529// create TAZ Sink using GNEChange_TAZElement and value of TAZChild default parameters1530GNETAZSourceSink* source = new GNETAZSourceSink(SUMO_TAG_TAZSOURCE, myCurrentTAZ->getTAZ(), edge, myTAZChildDefaultParameters->getDefaultTAZSourceWeight());1531myViewNet->getUndoList()->add(new GNEChange_TAZSourceSink(source, true), true);1532// create TAZ Sink using GNEChange_TAZElement and value of TAZChild default parameters1533GNETAZSourceSink* sink = new GNETAZSourceSink(SUMO_TAG_TAZSINK, myCurrentTAZ->getTAZ(), edge, myTAZChildDefaultParameters->getDefaultTAZSinkWeight());1534myViewNet->getUndoList()->add(new GNEChange_TAZSourceSink(sink, true), true);1535// always refresh TAZ Edges after adding TAZSources/Sinks1536myCurrentTAZ->refreshTAZEdges();1537// update selected button1538myTAZChildDefaultParameters->updateSelectEdgesButton();1539return true;1540} else {1541throw ProcessError("Edge cannot be null");1542}1543}154415451546void1547GNETAZFrame::dropTAZMembers() {1548// iterate over all TAZEdges1549for (const auto& TAZEdgeColor : myCurrentTAZ->getTAZEdges()) {1550// enable save changes button1551myTAZSaveChanges->enableButtonsAndBeginUndoList();1552// remove Source and Sinks using GNEChange_TAZElement1553if (TAZEdgeColor.source) {1554myViewNet->getUndoList()->add(new GNEChange_TAZSourceSink(TAZEdgeColor.source, false), true);1555}1556if (TAZEdgeColor.sink) {1557myViewNet->getUndoList()->add(new GNEChange_TAZSourceSink(TAZEdgeColor.sink, false), true);1558}1559}1560// always refresh TAZ Edges after removing TAZSources/Sinks1561myCurrentTAZ->refreshTAZEdges();1562}15631564/****************************************************************************/156515661567