Path: blob/main/src/netedit/dialogs/fix/GNEFixNetworkElements.cpp
169684 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 GNEFixNetworkElements.cpp14/// @author Pablo Alvarez Lopez15/// @date Jun 202216///17// Dialog used to fix network elements during saving18/****************************************************************************/1920#include <netedit/GNEApplicationWindow.h>21#include <netedit/GNENet.h>22#include <netedit/GNETagProperties.h>23#include <netedit/GNEUndoList.h>2425#include "GNEFixNetworkElements.h"2627// ===========================================================================28// FOX callback mapping29// ===========================================================================3031FXDEFMAP(GNEFixNetworkElements::FixEdgeOptions) FixEdgeOptionsMap[] = {32FXMAPFUNC(SEL_COMMAND, MID_CHOOSEN_OPERATION, GNEFixNetworkElements::FixEdgeOptions::onCmdSelectOption)33};3435FXDEFMAP(GNEFixNetworkElements::FixCrossingOptions) FixCrossingOptionsMap[] = {36FXMAPFUNC(SEL_COMMAND, MID_CHOOSEN_OPERATION, GNEFixNetworkElements::FixCrossingOptions::onCmdSelectOption)37};3839// Object abstract implementation40FXIMPLEMENT(GNEFixNetworkElements::FixEdgeOptions, MFXGroupBoxModule, FixEdgeOptionsMap, ARRAYNUMBER(FixEdgeOptionsMap))41FXIMPLEMENT(GNEFixNetworkElements::FixCrossingOptions, MFXGroupBoxModule, FixCrossingOptionsMap, ARRAYNUMBER(FixCrossingOptionsMap))4243// ===========================================================================44// member method definitions45// ===========================================================================4647// ---------------------------------------------------------------------------48// GNEFixNetworkElements::FixEdgeOptions - methods49// ---------------------------------------------------------------------------5051GNEFixNetworkElements::FixEdgeOptions::FixEdgeOptions(GNEFixNetworkElements* fixNetworkElementsParent) :52GNEFixElementsDialog<GNENetworkElement*>::FixOptions(fixNetworkElementsParent, fixNetworkElementsParent->myLeftFrame, "Edges") {53// Remove invalid edges54myRemoveInvalidEdges = GUIDesigns::buildFXRadioButton(myLeftFrameOptions,55TL("Remove invalid edges"), "",56TL("Remove invalid edges"),57this, MID_CHOOSEN_OPERATION, GUIDesignRadioButtonFix);58// Save invalid edges59mySaveInvalidEdges = GUIDesigns::buildFXRadioButton(myLeftFrameOptions,60TL("Save invalid edges"), "",61TL("Save invalid edges"),62this, MID_CHOOSEN_OPERATION, GUIDesignRadioButtonFix);63// Select invalid edges64mySelectInvalidEdges = GUIDesigns::buildFXRadioButton(myRightFrameOptions,65TL("Select invalid edges"), "",66TL("Select invalid edges and abort saving"),67this, MID_CHOOSEN_OPERATION, GUIDesignRadioButtonFix);68// register options69registerOption(myRemoveInvalidEdges);70registerOption(mySaveInvalidEdges);71registerOption(mySelectInvalidEdges);72// set option "removeInvalidEdges" as default73myRemoveInvalidEdges->setCheck(true);74}757677void78GNEFixNetworkElements::FixEdgeOptions::selectInternalTestSolution(const std::string& /*solution*/) {79// finish80}818283bool84GNEFixNetworkElements::FixEdgeOptions::applyFixOption() {85if (myConflictedElements.size() > 0) {86auto net = myFixElementDialogParent->getApplicationWindow()->getViewNet()->getNet();87auto undoList = myFixElementDialogParent->getApplicationWindow()->getUndoList();88// continue depending of solution89if (myRemoveInvalidEdges->getCheck() == TRUE) {90// begin undo list91undoList->begin(GUIIcon::EDGE, TL("delete invalid edges"));92// iterate over invalid edges to delete it93for (const auto& conflictedElement : myConflictedElements) {94net->deleteEdge(net->getAttributeCarriers()->retrieveEdge(conflictedElement.getID()), undoList, false);95}96// end undo list97undoList->end();98} else if (mySelectInvalidEdges->getCheck() == TRUE) {99// begin undo list100undoList->begin(GUIIcon::EDGE, TL("select invalid edges"));101// iterate over invalid single lane elements to select all elements102for (const auto& conflictedElement : myConflictedElements) {103conflictedElement.getElement()->setAttribute(GNE_ATTR_SELECTED, "true", undoList);104}105// end undo list106undoList->end();107// abort saving108return false;109}110}111return true;112}113114115long116GNEFixNetworkElements::FixEdgeOptions::onCmdSelectOption(FXObject* obj, FXSelector, void*) {117if (obj == myRemoveInvalidEdges) {118myRemoveInvalidEdges->setCheck(true);119mySaveInvalidEdges->setCheck(false);120mySelectInvalidEdges->setCheck(false);121} else if (obj == mySaveInvalidEdges) {122myRemoveInvalidEdges->setCheck(false);123mySaveInvalidEdges->setCheck(true);124mySelectInvalidEdges->setCheck(false);125} else if (obj == mySelectInvalidEdges) {126myRemoveInvalidEdges->setCheck(false);127mySaveInvalidEdges->setCheck(false);128mySelectInvalidEdges->setCheck(true);129}130return 1;131}132133// ---------------------------------------------------------------------------134// GNEFixNetworkElements::FixCrossingOptions - methods135// ---------------------------------------------------------------------------136137GNEFixNetworkElements::FixCrossingOptions::FixCrossingOptions(GNEFixNetworkElements* fixNetworkElementsParent) :138GNEFixElementsDialog<GNENetworkElement*>::FixOptions(fixNetworkElementsParent, fixNetworkElementsParent->myLeftFrame, "Crossings") {139// Remove invalid crossings140myRemoveInvalidCrossings = GUIDesigns::buildFXRadioButton(myLeftFrameOptions,141TL("Remove invalid crossings"), "",142TL("Remove invalid crossings"),143this, MID_CHOOSEN_OPERATION, GUIDesignRadioButtonFix);144// Save invalid crossings145mySaveInvalidCrossings = GUIDesigns::buildFXRadioButton(myLeftFrameOptions,146TL("Save invalid crossings"), "",147TL("Save invalid crossings"),148this, MID_CHOOSEN_OPERATION, GUIDesignRadioButtonFix);149// Select invalid crossing150mySelectInvalidCrossings = GUIDesigns::buildFXRadioButton(myRightFrameOptions,151TL("Select invalid crossing"), "",152TL("Select invalid crossing and abort saving"),153this, MID_CHOOSEN_OPERATION, GUIDesignRadioButtonFix);154// register options155registerOption(myRemoveInvalidCrossings);156registerOption(mySaveInvalidCrossings);157registerOption(mySelectInvalidCrossings);158// by default remove invalid crossings159myRemoveInvalidCrossings->setCheck(TRUE);160}161162163void164GNEFixNetworkElements::FixCrossingOptions::selectInternalTestSolution(const std::string& solution) {165// choose solution166if (solution == "removeInvalidCrossings") {167myRemoveInvalidCrossings->setCheck(TRUE, TRUE);168} else if (solution == "saveInvalidCrossings") {169mySaveInvalidCrossings->setCheck(TRUE, TRUE);170} else if (solution == "selectInvalidCrossings") {171mySelectInvalidCrossings->setCheck(TRUE, TRUE);172}173}174175176bool177GNEFixNetworkElements::FixCrossingOptions::applyFixOption() {178if (myConflictedElements.size() > 0) {179auto net = myFixElementDialogParent->getApplicationWindow()->getViewNet()->getNet();180auto undoList = myFixElementDialogParent->getApplicationWindow()->getUndoList();181// continue depending of solution182if (myRemoveInvalidCrossings->getCheck() == TRUE) {183// begin undo list184undoList->begin(GUIIcon::CROSSING, TL("delete invalid crossings"));185// iterate over invalid crossings to delete it186for (const auto& conflictedElement : myConflictedElements) {187net->deleteCrossing(net->getAttributeCarriers()->retrieveCrossing(conflictedElement.getElement()), undoList);188}189// end undo list190undoList->end();191} else if (mySelectInvalidCrossings->getCheck() == TRUE) {192// begin undo list193undoList->begin(GUIIcon::CROSSING, TL("select invalid crossings"));194// iterate over invalid single lane elements to select all elements195for (const auto& conflictedElement : myConflictedElements) {196conflictedElement.getElement()->setAttribute(GNE_ATTR_SELECTED, "true", undoList);197}198// end undo list199undoList->end();200// abort saving201return false;202}203}204return true;205}206207208long209GNEFixNetworkElements::FixCrossingOptions::onCmdSelectOption(FXObject* obj, FXSelector, void*) {210if (obj == myRemoveInvalidCrossings) {211myRemoveInvalidCrossings->setCheck(true);212mySaveInvalidCrossings->setCheck(false);213mySelectInvalidCrossings->setCheck(false);214} else if (obj == mySaveInvalidCrossings) {215myRemoveInvalidCrossings->setCheck(false);216mySaveInvalidCrossings->setCheck(true);217mySelectInvalidCrossings->setCheck(false);218} else if (obj == mySelectInvalidCrossings) {219myRemoveInvalidCrossings->setCheck(false);220mySaveInvalidCrossings->setCheck(false);221mySelectInvalidCrossings->setCheck(true);222}223return 1;224}225226// ---------------------------------------------------------------------------227// GNEFixNetworkElements - methods228// ---------------------------------------------------------------------------229230GNEFixNetworkElements::GNEFixNetworkElements(GNEApplicationWindow* mainWindow,231const std::vector<GNENetworkElement*>& elements) :232GNEFixElementsDialog(mainWindow, TL("Fix network elements problems"), GUIIcon::SUPERMODENETWORK,233DialogType::FIX_NETWORKELEMENTS) {234// create fix edge options235myFixEdgeOptions = new FixEdgeOptions(this);236// create fix crossing options237myFixCrossingOptions = new FixCrossingOptions(this);238// split invalidNetworkElements in four groups239std::vector<ConflictElement> invalidEdges, invalidCrossings;240// fill groups241for (const auto& invalidNetworkElement : elements) {242// create conflict element243auto fixElement = ConflictElement(invalidNetworkElement,244invalidNetworkElement->getID(),245invalidNetworkElement->getACIcon(),246invalidNetworkElement->getNetworkElementProblem());247// add depending of element type248if (invalidNetworkElement->getTagProperty()->getTag() == SUMO_TAG_EDGE) {249invalidEdges.push_back(fixElement);250} else if (invalidNetworkElement->getTagProperty()->getTag() == SUMO_TAG_CROSSING) {251invalidCrossings.push_back(fixElement);252}253}254// fill options255myFixEdgeOptions->setInvalidElements(invalidEdges);256myFixCrossingOptions->setInvalidElements(invalidCrossings);257// open modal dialog258openDialog();259}260261262GNEFixNetworkElements::~GNEFixNetworkElements() {}263264/****************************************************************************/265266267