Path: blob/main/src/netedit/elements/data/GNEDataHandler.cpp
193678 views
/****************************************************************************/1// Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.dev/sumo2// Copyright (C) 2001-2026 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 GNEDataHandler.cpp14/// @author Pablo Alvarez Lopez15/// @date Jan 202016///17// Builds data objects for netedit18/****************************************************************************/1920#include <netedit/changes/GNEChange_DataInterval.h>21#include <netedit/changes/GNEChange_DataSet.h>22#include <netedit/changes/GNEChange_GenericData.h>23#include <netedit/dialogs/basic/GNEOverwriteElement.h>24#include <netedit/elements/data/GNEDataInterval.h>25#include <netedit/elements/data/GNEEdgeData.h>26#include <netedit/elements/data/GNEEdgeRelData.h>27#include <netedit/elements/data/GNETAZRelData.h>28#include <netedit/GNEApplicationWindow.h>29#include <netedit/GNENet.h>30#include <netedit/GNETagProperties.h>31#include <netedit/GNEUndoList.h>32#include <netedit/GNEViewNet.h>33#include <utils/gui/div/GUIDesigns.h>3435#include "GNEDataHandler.h"3637// ===========================================================================38// member method definitions39// ===========================================================================4041GNEDataHandler::GNEDataHandler(GNENet* net, FileBucket* fileBucket, const bool allowUndoRedo) :42DataHandler(fileBucket),43myNet(net),44myAllowUndoRedo(allowUndoRedo) {45}464748GNEDataHandler::~GNEDataHandler() {49// update options based in current buckets50myNet->getGNEApplicationWindow()->getFileBucketHandler()->updateOptions();51}525354bool55GNEDataHandler::buildDataSet(const std::string& id) {56// first check if dataSet exist57if (!checkValidAdditionalID(SUMO_TAG_DATASET, id)) {58return false;59} else if (!checkDuplicatedDataSet(id)) {60return false;61} else {62GNEDataSet* dataSet = new GNEDataSet(id, myNet, myFileBucket);63if (myAllowUndoRedo) {64myNet->getUndoList()->begin(dataSet, TL("add data set"));65myNet->getUndoList()->add(new GNEChange_DataSet(dataSet, true), true);66myNet->getUndoList()->end();67} else {68// insert dataSet without allowing undo/redo69myNet->getAttributeCarriers()->insertDataSet(dataSet);70dataSet->incRef("buildDataSet");71}72return true;73}74}757677bool78GNEDataHandler::buildDataInterval(const CommonXMLStructure::SumoBaseObject* /* sumoBaseObject */,79const std::string& dataSetID, const double begin, const double end) {80// get dataSet81GNEDataSet* dataSet = myNet->getAttributeCarriers()->retrieveDataSet(dataSetID, false);82// first check if dataSet exist83if (dataSet == nullptr) {84// create dataset AND data interval85dataSet = new GNEDataSet(dataSetID, myNet, myFileBucket);86GNEDataInterval* dataInterval = new GNEDataInterval(dataSet, begin, end);87if (myAllowUndoRedo) {88myNet->getUndoList()->begin(dataInterval, TL("add data set and data interval"));89myNet->getUndoList()->add(new GNEChange_DataSet(dataSet, true), true);90myNet->getUndoList()->add(new GNEChange_DataInterval(dataInterval, true), true);91myNet->getUndoList()->end();92} else {93// insert dataSet allowing undo/redo94myNet->getAttributeCarriers()->insertDataSet(dataSet);95dataSet->incRef("buildDataInterval");96// insert dataInterval without allowing undo/redo97dataSet->addDataIntervalChild(dataInterval);98dataInterval->incRef("buildDataInterval");99}100return true;101} else if (dataSet->retrieveInterval(begin, end) == nullptr) {102GNEDataInterval* dataInterval = new GNEDataInterval(dataSet, begin, end);103if (myAllowUndoRedo) {104myNet->getUndoList()->begin(dataInterval, TL("add data interval"));105myNet->getUndoList()->add(new GNEChange_DataInterval(dataInterval, true), true);106myNet->getUndoList()->end();107} else {108// insert dataInterval without allowing undo/redo109dataSet->addDataIntervalChild(dataInterval);110dataInterval->incRef("buildDataInterval");111}112return true;113} else {114return false;115}116}117118119bool120GNEDataHandler::buildEdgeData(const CommonXMLStructure::SumoBaseObject* sumoBaseObject, const std::string& edgeID,121const Parameterised::Map& parameters) {122// get dataSet123GNEDataSet* dataSet = myNet->getAttributeCarriers()->retrieveDataSet(sumoBaseObject->getParentSumoBaseObject()->getStringAttribute(SUMO_ATTR_ID), false);124if (dataSet) {125// get interval126GNEDataInterval* dataInterval = dataSet->retrieveInterval(127sumoBaseObject->getParentSumoBaseObject()->getDoubleAttribute(SUMO_ATTR_BEGIN),128sumoBaseObject->getParentSumoBaseObject()->getDoubleAttribute(SUMO_ATTR_END));129if (dataInterval) {130// get data131GNEEdge* edge = myNet->getAttributeCarriers()->retrieveEdge(edgeID, false);132if (edge == nullptr) {133return writeErrorInvalidParent(GNE_TAG_EDGEREL_SINGLE, {SUMO_TAG_EDGE});134} else if (dataInterval->edgeRelSingleExists(edge)) {135return writeError(TLF("There is already a edgeRel defined in edge '%'.", edge));136} else {137// create edge data138GNEGenericData* edgeData = new GNEEdgeData(dataInterval, edge, parameters);139if (myAllowUndoRedo) {140myNet->getUndoList()->begin(edgeData, TL("add edge rel"));141myNet->getUndoList()->add(new GNEChange_GenericData(edgeData, true), true);142myNet->getUndoList()->end();143} else {144dataInterval->addGenericDataChild(edgeData);145edge->addChildElement(edgeData);146edgeData->incRef("buildEdgeData");147}148return true;149}150} else {151return writeErrorInvalidParent(GNE_TAG_EDGEREL_SINGLE, {SUMO_TAG_DATAINTERVAL});152}153} else {154return writeErrorInvalidParent(GNE_TAG_EDGEREL_SINGLE, {SUMO_TAG_DATASET});155}156}157158159bool160GNEDataHandler::buildEdgeRelationData(const CommonXMLStructure::SumoBaseObject* sumoBaseObject, const std::string& fromEdgeID,161const std::string& toEdgeID, const Parameterised::Map& parameters) {162// get dataSet163GNEDataSet* dataSet = myNet->getAttributeCarriers()->retrieveDataSet(sumoBaseObject->getParentSumoBaseObject()->getStringAttribute(SUMO_ATTR_ID), false);164if (dataSet != nullptr) {165// get interval166GNEDataInterval* dataInterval = dataSet->retrieveInterval(167sumoBaseObject->getParentSumoBaseObject()->getDoubleAttribute(SUMO_ATTR_BEGIN),168sumoBaseObject->getParentSumoBaseObject()->getDoubleAttribute(SUMO_ATTR_END));169if (dataInterval != nullptr) {170// get data171GNEEdge* const fromEdge = myNet->getAttributeCarriers()->retrieveEdge(fromEdgeID, false);172GNEEdge* const toEdge = myNet->getAttributeCarriers()->retrieveEdge(toEdgeID, false);173if (fromEdge == nullptr) {174return writeErrorInvalidParent(SUMO_TAG_EDGEREL, {SUMO_TAG_EDGE}, fromEdgeID);175} else if (toEdge == nullptr) {176return writeErrorInvalidParent(SUMO_TAG_EDGEREL, {SUMO_TAG_EDGE}, toEdgeID);177} else if (dataInterval->edgeRelExists(fromEdge, toEdge)) {178return writeError(TLF("There is already a edgeRel defined between '%' and '%'.", fromEdgeID, toEdgeID));179} else {180GNEGenericData* edgeData = new GNEEdgeRelData(dataInterval, fromEdge, toEdge, parameters);181if (myAllowUndoRedo) {182myNet->getUndoList()->begin(edgeData, TL("add edge rel"));183myNet->getUndoList()->add(new GNEChange_GenericData(edgeData, true), true);184myNet->getUndoList()->end();185} else {186dataInterval->addGenericDataChild(edgeData);187fromEdge->addChildElement(edgeData);188toEdge->addChildElement(edgeData);189edgeData->incRef("buildEdgeRelationData");190}191return true;192}193} else {194return writeErrorInvalidParent(SUMO_TAG_EDGEREL, {SUMO_TAG_DATAINTERVAL});195}196} else {197return writeErrorInvalidParent(SUMO_TAG_EDGEREL, {SUMO_TAG_DATASET});198}199}200201202bool203GNEDataHandler::buildTAZRelationData(const CommonXMLStructure::SumoBaseObject* sumoBaseObject, const std::string& fromTAZID,204const std::string& toTAZID, const Parameterised::Map& parameters) {205// get dataSet206GNEDataSet* dataSet = myNet->getAttributeCarriers()->retrieveDataSet(sumoBaseObject->getParentSumoBaseObject()->getStringAttribute(SUMO_ATTR_ID), false);207if (dataSet != nullptr) {208// get interval209GNEDataInterval* dataInterval = dataSet->retrieveInterval(210sumoBaseObject->getParentSumoBaseObject()->getDoubleAttribute(SUMO_ATTR_BEGIN),211sumoBaseObject->getParentSumoBaseObject()->getDoubleAttribute(SUMO_ATTR_END));212if (dataInterval != nullptr) {213// get from TAZs214GNEAdditional* fromTAZ = myNet->getAttributeCarriers()->retrieveAdditional(SUMO_TAG_TAZ, fromTAZID, false);215GNEAdditional* toTAZ = myNet->getAttributeCarriers()->retrieveAdditional(SUMO_TAG_TAZ, toTAZID, false);216if (fromTAZ == nullptr) {217return writeErrorInvalidParent(SUMO_TAG_TAZREL, {SUMO_TAG_TAZ}, fromTAZID);218} else if (toTAZ == nullptr) {219return writeErrorInvalidParent(SUMO_TAG_TAZREL, {SUMO_TAG_TAZ}, toTAZID);220} else if ((fromTAZ != toTAZ) && dataInterval->TAZRelExists(fromTAZ, toTAZ)) {221return writeError(TLF("There is already a TAZ rel defined between '%' and '%'.", fromTAZID, toTAZID));222} else if ((fromTAZ == toTAZ) && dataInterval->TAZRelExists(fromTAZ)) {223return writeError(TLF("There is already a TAZ rel defined in '%'.", toTAZID));224} else if (fromTAZ == toTAZ) {225GNEGenericData* edgeData = new GNETAZRelData(dataInterval, fromTAZ, parameters);226if (myAllowUndoRedo) {227myNet->getUndoList()->begin(edgeData, TL("add TAZ rel"));228myNet->getUndoList()->add(new GNEChange_GenericData(edgeData, true), true);229myNet->getUndoList()->end();230} else {231dataInterval->addGenericDataChild(edgeData);232fromTAZ->addChildElement(edgeData);233edgeData->incRef("buildTAZRelationData");234}235return true;236} else {237GNEGenericData* edgeData = new GNETAZRelData(dataInterval, fromTAZ, toTAZ, parameters);238if (myAllowUndoRedo) {239myNet->getUndoList()->begin(edgeData, TL("add TAZ rel"));240myNet->getUndoList()->add(new GNEChange_GenericData(edgeData, true), true);241myNet->getUndoList()->end();242} else {243dataInterval->addGenericDataChild(edgeData);244fromTAZ->addChildElement(edgeData);245toTAZ->addChildElement(edgeData);246edgeData->incRef("buildTAZRelationData");247}248return true;249}250} else {251return writeErrorInvalidParent(SUMO_TAG_TAZREL, {SUMO_TAG_DATAINTERVAL});252}253} else {254return writeErrorInvalidParent(SUMO_TAG_TAZREL, {SUMO_TAG_DATASET});255}256}257258259bool260GNEDataHandler::checkDuplicatedDataSet(const std::string& id) {261// retrieve data set262auto dataSet = myNet->getAttributeCarriers()->retrieveDataSet(id, false);263// if demand exist, check if overwrite (delete)264if (dataSet) {265if (myOverwriteElements) {266// delete data element (and all of their childrens)267myNet->deleteDataSet(dataSet, myNet->getUndoList());268} else if (myRemainElements) {269// duplicated dataset270return writeWarningDuplicated(SUMO_TAG_DATASET, id, SUMO_TAG_DATASET);271} else {272// open overwrite dialog273GNEOverwriteElement overwriteElementDialog(this, dataSet);274// continue depending of result275if (overwriteElementDialog.getResult() == GNEOverwriteElement::Result::ACCEPT) {276// delete data element (and all of their childrens)277myNet->deleteDataSet(dataSet, myNet->getUndoList());278} else if (overwriteElementDialog.getResult() == GNEOverwriteElement::Result::CANCEL) {279// duplicated dataset280return writeWarningDuplicated(SUMO_TAG_DATASET, id, SUMO_TAG_DATASET);281} else {282return false;283}284}285}286return true;287}288289/****************************************************************************/290291292