Path: blob/main/src/netedit/dialogs/fix/GNEFixAdditionalElementsDialog.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 GNEFixAdditionalElementsDialog.cpp14/// @author Pablo Alvarez Lopez15/// @date Jul 201716///17// Dialog used to fix additional elements18/****************************************************************************/1920#include <netedit/GNEApplicationWindow.h>21#include <netedit/GNENet.h>22#include <netedit/GNETagProperties.h>23#include <netedit/GNEUndoList.h>2425#include "GNEFixAdditionalElementsDialog.h"2627// ===========================================================================28// FOX callback mapping29// ===========================================================================3031FXDEFMAP(GNEFixAdditionalElementsDialog::PositionOptions) PositionOptionsMap[] = {32FXMAPFUNC(SEL_COMMAND, MID_CHOOSEN_OPERATION, GNEFixAdditionalElementsDialog::PositionOptions::onCmdSelectOption)33};3435FXDEFMAP(GNEFixAdditionalElementsDialog::ConsecutiveLaneOptions) ConsecutiveLaneOptionsMap[] = {36FXMAPFUNC(SEL_COMMAND, MID_CHOOSEN_OPERATION, GNEFixAdditionalElementsDialog::ConsecutiveLaneOptions::onCmdSelectOption)37};3839// Object abstract implementation40FXIMPLEMENT(GNEFixAdditionalElementsDialog::PositionOptions, MFXGroupBoxModule, PositionOptionsMap, ARRAYNUMBER(PositionOptionsMap))41FXIMPLEMENT(GNEFixAdditionalElementsDialog::ConsecutiveLaneOptions, MFXGroupBoxModule, ConsecutiveLaneOptionsMap, ARRAYNUMBER(ConsecutiveLaneOptionsMap))4243// ===========================================================================44// member method definitions45// ===========================================================================4647// ---------------------------------------------------------------------------48// GNEFixAdditionalElementsDialog::PositionOptions - methods49// ---------------------------------------------------------------------------5051GNEFixAdditionalElementsDialog::PositionOptions::PositionOptions(GNEFixAdditionalElementsDialog* fixAdditionalPositions) :52GNEFixElementsDialog<GNEAdditional*>::FixOptions(fixAdditionalPositions, fixAdditionalPositions->myLeftFrame,53TL("Select a solution for StoppingPlaces and E2 detectors")) {54// activate friendly position55myActivateFriendlyPosition = GUIDesigns::buildFXRadioButton(myLeftFrameOptions,56TL("Activate friendlyPos and save"), "",57TL("Friendly pos parameter will be activated in all stopping places and E2 detectors"),58this, MID_CHOOSEN_OPERATION, GUIDesignRadioButtonFix);59// save invalid positions60mySaveInvalids = GUIDesigns::buildFXRadioButton(myLeftFrameOptions,61TL("Save invalid positions"), "",62TL("Save stopping places and E2 detectors with invalid positions"),63this, MID_CHOOSEN_OPERATION, GUIDesignRadioButtonFix);64// fix positions65myFixPositions = GUIDesigns::buildFXRadioButton(myRightFrameOptions,66TL("Fix positions and save"), "",67TL("Position of stopping places and E2 detectors will be fixed"),68this, MID_CHOOSEN_OPERATION, GUIDesignRadioButtonFix);69// select invalids70mySelectInvalids = GUIDesigns::buildFXRadioButton(myRightFrameOptions,71TL("Select invalid additionals"), "",72TL("Cancel saving of additionals and select invalid stopping places and E2 detectors"),73this, MID_CHOOSEN_OPERATION, GUIDesignRadioButtonFix);74// register options75registerOption(myActivateFriendlyPosition);76registerOption(mySaveInvalids);77registerOption(myFixPositions);78registerOption(mySelectInvalids);79// set option "activateFriendlyPosition" as default80myActivateFriendlyPosition->setCheck(true);81}828384void85GNEFixAdditionalElementsDialog::PositionOptions::selectInternalTestSolution(const std::string& solution) {86// choose solution87if (solution == "savePositionInvalids") {88mySaveInvalids->setCheck(TRUE, TRUE);89} else if (solution == "fixPositions") {90myFixPositions->setCheck(TRUE, TRUE);91} else if (solution == "selectPositionInvalids") {92mySelectInvalids->setCheck(TRUE, TRUE);93} else if (solution == "activatePositionFriendlyPos") {94myActivateFriendlyPosition->setCheck(TRUE, TRUE);95}96}979899bool100GNEFixAdditionalElementsDialog::PositionOptions::applyFixOption() {101if (myConflictedElements.size() > 0) {102auto undoList = myFixElementDialogParent->getApplicationWindow()->getUndoList();103// continue depending of solution104if (myActivateFriendlyPosition->getCheck() == TRUE) {105undoList->begin(myConflictedElements.front().getElement(),106TLF("change % of invalid additionals", toString(SUMO_ATTR_FRIENDLY_POS)));107// iterate over invalid single lane elements to enable friendly position108for (const auto& conflictedElement : myConflictedElements) {109conflictedElement.getElement()->setAttribute(SUMO_ATTR_FRIENDLY_POS, "true", undoList);110}111undoList->end();112} else if (myFixPositions->getCheck() == TRUE) {113undoList->begin(myConflictedElements.front().getElement(),114TL("fix positions of invalid additionals"));115// iterate over invalid single lane elements to fix positions116for (const auto& conflictedElement : myConflictedElements) {117conflictedElement.getElement()->fixAdditionalProblem();118}119undoList->end();120} else if (mySelectInvalids->getCheck() == TRUE) {121undoList->begin(myConflictedElements.front().getElement(),122TL("select invalid additionals"));123// iterate over invalid single lane elements to select all elements124for (const auto& conflictedElement : myConflictedElements) {125conflictedElement.getElement()->setAttribute(GNE_ATTR_SELECTED, "true", undoList);126}127undoList->end();128// abort saving129return false;130}131}132return true;133}134135136long137GNEFixAdditionalElementsDialog::PositionOptions::onCmdSelectOption(FXObject* obj, FXSelector, void*) {138if (obj == myActivateFriendlyPosition) {139myActivateFriendlyPosition->setCheck(true);140myFixPositions->setCheck(false);141mySaveInvalids->setCheck(false);142mySelectInvalids->setCheck(false);143} else if (obj == myFixPositions) {144myActivateFriendlyPosition->setCheck(false);145myFixPositions->setCheck(true);146mySaveInvalids->setCheck(false);147mySelectInvalids->setCheck(false);148} else if (obj == mySaveInvalids) {149myActivateFriendlyPosition->setCheck(false);150myFixPositions->setCheck(false);151mySaveInvalids->setCheck(true);152mySelectInvalids->setCheck(false);153} else if (obj == mySelectInvalids) {154myActivateFriendlyPosition->setCheck(false);155myFixPositions->setCheck(false);156mySaveInvalids->setCheck(false);157mySelectInvalids->setCheck(true);158}159return 1;160}161162// ---------------------------------------------------------------------------163// GNEFixAdditionalElementsDialog::ConsecutiveLaneOptions - methods164// ---------------------------------------------------------------------------165166GNEFixAdditionalElementsDialog::ConsecutiveLaneOptions::ConsecutiveLaneOptions(GNEFixAdditionalElementsDialog* fixAdditionalPositions) :167GNEFixElementsDialog<GNEAdditional*>::FixOptions(fixAdditionalPositions, fixAdditionalPositions->myLeftFrame,168TL("Select a solution for Multilane E2 detectors")) {169// build connection between lanes170myBuildConnectionBetweenLanes = GUIDesigns::buildFXRadioButton(myLeftFrameOptions,171TL("Build connections between lanes"), "",172TL("New connections will be created between non-connected lanes"),173this, MID_CHOOSEN_OPERATION, GUIDesignRadioButtonFix);174// remove invalid elements175myRemoveInvalidElements = GUIDesigns::buildFXRadioButton(myLeftFrameOptions,176TL("Remove invalid E2 detectors"), "",177TL("Remove Multilane E2 Detectors with non-connected lanes"),178this, MID_CHOOSEN_OPERATION, GUIDesignRadioButtonFix);179// activate friendly position180myActivateFriendlyPosition = GUIDesigns::buildFXRadioButton(myRightFrameOptions,181TL("Activate friendlyPos and save"), "",182TL("Friendly pos parameter will be activated in all stopping places and E2 detectors"),183this, MID_CHOOSEN_OPERATION, GUIDesignRadioButtonFix);184// fix positions185myFixPositions = GUIDesigns::buildFXRadioButton(myRightFrameOptions,186TL("Fix positions and save"), "",187TL("Position of stopping places and E2 detectors will be fixed"),188this, MID_CHOOSEN_OPERATION, GUIDesignRadioButtonFix);189// register options190registerOption(myBuildConnectionBetweenLanes);191registerOption(myRemoveInvalidElements);192registerOption(myActivateFriendlyPosition);193registerOption(myFixPositions);194// leave option "buildConnectionBetweenLanes" and "activateFriendlyPosition" as default195myBuildConnectionBetweenLanes->setCheck(true);196myActivateFriendlyPosition->setCheck(true);197}198199200void201GNEFixAdditionalElementsDialog::ConsecutiveLaneOptions::selectInternalTestSolution(const std::string& /*solution*/) {202}203204205bool206GNEFixAdditionalElementsDialog::ConsecutiveLaneOptions::applyFixOption() {207if (myConflictedElements.size() > 0) {208auto net = myFixElementDialogParent->getApplicationWindow()->getViewNet()->getNet();209auto undoList = myFixElementDialogParent->getApplicationWindow()->getUndoList();210// all fix implies undo-redo211undoList->begin(myConflictedElements.front().getElement(),212TL("fix multilane additionals problems"));213// continue depending of solution214if (myBuildConnectionBetweenLanes->getCheck() == TRUE) {215// iterate over invalid single lane elements to enable friendly position216for (const auto& conflictedElement : myConflictedElements) {217conflictedElement.getElement()->fixAdditionalProblem();218}219// we need to check if after first fix there is still invalid MultiLane Additionals with errors220const std::vector<ConflictElement> copyOfConflictedElements = myConflictedElements;221myConflictedElements.clear();222for (const auto& conflictedElement : copyOfConflictedElements) {223if (!conflictedElement.getElement()->isAdditionalValid()) {224myConflictedElements.push_back(conflictedElement);225}226}227} else if (myRemoveInvalidElements->getCheck() == TRUE) {228// iterate over invalid single lane elements to fix positions229for (const auto& conflictedElement : myConflictedElements) {230net->deleteAdditional(conflictedElement.getElement(), undoList);231}232// clear myInvalidMultiLaneAdditionals due there isn't more invalid multi lane additionals233myConflictedElements.clear();234}235// fix problem of positions236if (myActivateFriendlyPosition->getCheck() == TRUE) {237// iterate over invalid single lane elements to enable friendly position238for (const auto& conflictedElement : myConflictedElements) {239conflictedElement.getElement()->setAttribute(SUMO_ATTR_FRIENDLY_POS, "true", undoList);240}241} else if (myFixPositions->getCheck() == TRUE) {242// iterate over invalid single lane elements to fix positions243for (const auto& conflictedElement : myConflictedElements) {244conflictedElement.getElement()->fixAdditionalProblem();245}246}247// end undo list248undoList->end();249}250return true;251}252253254long255GNEFixAdditionalElementsDialog::ConsecutiveLaneOptions::onCmdSelectOption(FXObject* obj, FXSelector, void*) {256// set top buttons257if (obj == myBuildConnectionBetweenLanes) {258myBuildConnectionBetweenLanes->setCheck(true);259myRemoveInvalidElements->setCheck(false);260} else if (obj == myRemoveInvalidElements) {261myBuildConnectionBetweenLanes->setCheck(false);262myRemoveInvalidElements->setCheck(true);263}264// set down buttons265if (obj == myActivateFriendlyPosition) {266myActivateFriendlyPosition->setCheck(true);267myFixPositions->setCheck(false);268} else if (obj == myFixPositions) {269myActivateFriendlyPosition->setCheck(false);270myFixPositions->setCheck(true);271}272return true;273}274275// ---------------------------------------------------------------------------276// GNEFixAdditionalElementsDialog - methods277// ---------------------------------------------------------------------------278279GNEFixAdditionalElementsDialog::GNEFixAdditionalElementsDialog(GNEApplicationWindow* mainWindow,280const std::vector<GNEAdditional*>& elements) :281GNEFixElementsDialog(mainWindow, TL("Fix additional problems"), GUIIcon::MODEADDITIONAL,282DialogType::FIX_ADDITIONALELEMENTS) {283// create position options284myPositionOptions = new PositionOptions(this);285// create consecutive lane options286myConsecutiveLaneOptions = new ConsecutiveLaneOptions(this);287// split invalidDemandElements in four groups288std::vector<ConflictElement> invalidSingleLanes, invalidMultiLanes;289// fill groups290for (const auto& invalidAdditionalElement : elements) {291// create conflict element292auto fixElement = ConflictElement(invalidAdditionalElement,293invalidAdditionalElement->getID(),294invalidAdditionalElement->getACIcon(),295invalidAdditionalElement->getAdditionalProblem());296// add depending of element type297if (invalidAdditionalElement->getTagProperty()->hasAttribute(SUMO_ATTR_LANE)) {298invalidSingleLanes.push_back(fixElement);299} else if (invalidAdditionalElement->getTagProperty()->hasAttribute(SUMO_ATTR_LANES)) {300invalidMultiLanes.push_back(fixElement);301}302}303// fill options304myPositionOptions->setInvalidElements(invalidSingleLanes);305myConsecutiveLaneOptions->setInvalidElements(invalidMultiLanes);306// open modal dialog307openDialog();308}309310311GNEFixAdditionalElementsDialog::~GNEFixAdditionalElementsDialog() {312}313314/****************************************************************************/315316317