Path: blob/main/src/netedit/elements/data/GNEDataHandler.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 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/GNENet.h>29#include <netedit/GNETagProperties.h>30#include <netedit/GNEUndoList.h>31#include <netedit/GNEViewNet.h>32#include <utils/gui/div/GUIDesigns.h>3334#include "GNEDataHandler.h"3536// ===========================================================================37// member method definitions38// ===========================================================================3940GNEDataHandler::GNEDataHandler(GNENet* net, const std::string& file, const bool allowUndoRedo) :41DataHandler(file),42myNet(net),43myAllowUndoRedo(allowUndoRedo) {44}454647GNEDataHandler::~GNEDataHandler() {}484950bool51GNEDataHandler::postParserTasks() {52// nothing to do53return true;54}555657bool58GNEDataHandler::buildDataSet(const std::string& id) {59// first check if dataSet exist60if (!checkValidAdditionalID(SUMO_TAG_DATASET, id)) {61return false;62} else if (!checkDuplicatedDataSet(id)) {63return false;64} else {65GNEDataSet* dataSet = new GNEDataSet(id, myNet, myFilename);66if (myAllowUndoRedo) {67myNet->getViewNet()->getUndoList()->begin(dataSet, TL("add data set"));68myNet->getViewNet()->getUndoList()->add(new GNEChange_DataSet(dataSet, true), true);69myNet->getViewNet()->getUndoList()->end();70} else {71// insert dataSet without allowing undo/redo72myNet->getAttributeCarriers()->insertDataSet(dataSet);73dataSet->incRef("buildDataSet");74}75return true;76}77}787980bool81GNEDataHandler::buildDataInterval(const CommonXMLStructure::SumoBaseObject* /* sumoBaseObject */,82const std::string& dataSetID, const double begin, const double end) {83// get dataSet84GNEDataSet* dataSet = myNet->getAttributeCarriers()->retrieveDataSet(dataSetID, false);85// first check if dataSet exist86if (dataSet == nullptr) {87// create dataset AND data interval88dataSet = new GNEDataSet(dataSetID, myNet, myFilename);89GNEDataInterval* dataInterval = new GNEDataInterval(dataSet, begin, end);90if (myAllowUndoRedo) {91myNet->getViewNet()->getUndoList()->begin(dataInterval, TL("add data set and data interval"));92myNet->getViewNet()->getUndoList()->add(new GNEChange_DataSet(dataSet, true), true);93myNet->getViewNet()->getUndoList()->add(new GNEChange_DataInterval(dataInterval, true), true);94myNet->getViewNet()->getUndoList()->end();95} else {96// insert dataSet allowing undo/redo97myNet->getAttributeCarriers()->insertDataSet(dataSet);98dataSet->incRef("buildDataInterval");99// insert dataInterval without allowing undo/redo100dataSet->addDataIntervalChild(dataInterval);101dataInterval->incRef("buildDataInterval");102}103return true;104} else if (dataSet->retrieveInterval(begin, end) == nullptr) {105GNEDataInterval* dataInterval = new GNEDataInterval(dataSet, begin, end);106if (myAllowUndoRedo) {107myNet->getViewNet()->getUndoList()->begin(dataInterval, TL("add data interval"));108myNet->getViewNet()->getUndoList()->add(new GNEChange_DataInterval(dataInterval, true), true);109myNet->getViewNet()->getUndoList()->end();110} else {111// insert dataInterval without allowing undo/redo112dataSet->addDataIntervalChild(dataInterval);113dataInterval->incRef("buildDataInterval");114}115return true;116} else {117return false;118}119}120121122bool123GNEDataHandler::buildEdgeData(const CommonXMLStructure::SumoBaseObject* sumoBaseObject, const std::string& edgeID,124const Parameterised::Map& parameters) {125// get dataSet126GNEDataSet* dataSet = myNet->getAttributeCarriers()->retrieveDataSet(sumoBaseObject->getParentSumoBaseObject()->getStringAttribute(SUMO_ATTR_ID), false);127if (dataSet) {128// get interval129GNEDataInterval* dataInterval = dataSet->retrieveInterval(130sumoBaseObject->getParentSumoBaseObject()->getDoubleAttribute(SUMO_ATTR_BEGIN),131sumoBaseObject->getParentSumoBaseObject()->getDoubleAttribute(SUMO_ATTR_END));132if (dataInterval) {133// get data134GNEEdge* edge = myNet->getAttributeCarriers()->retrieveEdge(edgeID, false);135if (edge == nullptr) {136return writeErrorInvalidParent(GNE_TAG_EDGEREL_SINGLE, SUMO_TAG_EDGE);137} else if (dataInterval->edgeRelSingleExists(edge)) {138return writeError(TLF("There is already a edgeRel defined in edge '%'.", edge));139} else {140// create edge data141GNEGenericData* edgeData = new GNEEdgeData(dataInterval, edge, parameters);142if (myAllowUndoRedo) {143myNet->getViewNet()->getUndoList()->begin(edgeData, TL("add edge rel"));144myNet->getViewNet()->getUndoList()->add(new GNEChange_GenericData(edgeData, true), true);145myNet->getViewNet()->getUndoList()->end();146} else {147dataInterval->addGenericDataChild(edgeData);148edge->addChildElement(edgeData);149edgeData->incRef("buildEdgeData");150}151return true;152}153} else {154return writeErrorInvalidParent(GNE_TAG_EDGEREL_SINGLE, SUMO_TAG_DATAINTERVAL);155}156} else {157return writeErrorInvalidParent(GNE_TAG_EDGEREL_SINGLE, SUMO_TAG_DATASET);158}159}160161162bool163GNEDataHandler::buildEdgeRelationData(const CommonXMLStructure::SumoBaseObject* sumoBaseObject, const std::string& fromEdgeID,164const std::string& toEdgeID, const Parameterised::Map& parameters) {165// get dataSet166GNEDataSet* dataSet = myNet->getAttributeCarriers()->retrieveDataSet(sumoBaseObject->getParentSumoBaseObject()->getStringAttribute(SUMO_ATTR_ID), false);167if (dataSet != nullptr) {168// get interval169GNEDataInterval* dataInterval = dataSet->retrieveInterval(170sumoBaseObject->getParentSumoBaseObject()->getDoubleAttribute(SUMO_ATTR_BEGIN),171sumoBaseObject->getParentSumoBaseObject()->getDoubleAttribute(SUMO_ATTR_END));172if (dataInterval != nullptr) {173// get data174GNEEdge* const fromEdge = myNet->getAttributeCarriers()->retrieveEdge(fromEdgeID, false);175GNEEdge* const toEdge = myNet->getAttributeCarriers()->retrieveEdge(toEdgeID, false);176if (fromEdge == nullptr) {177return writeErrorInvalidParent(SUMO_TAG_EDGEREL, SUMO_TAG_EDGE, fromEdgeID);178} else if (toEdge == nullptr) {179return writeErrorInvalidParent(SUMO_TAG_EDGEREL, SUMO_TAG_EDGE, toEdgeID);180} else if (dataInterval->edgeRelExists(fromEdge, toEdge)) {181return writeError(TLF("There is already a edgeRel defined between '%' and '%'.", fromEdgeID, toEdgeID));182} else {183GNEGenericData* edgeData = new GNEEdgeRelData(dataInterval, fromEdge, toEdge, parameters);184if (myAllowUndoRedo) {185myNet->getViewNet()->getUndoList()->begin(edgeData, TL("add edge rel"));186myNet->getViewNet()->getUndoList()->add(new GNEChange_GenericData(edgeData, true), true);187myNet->getViewNet()->getUndoList()->end();188} else {189dataInterval->addGenericDataChild(edgeData);190fromEdge->addChildElement(edgeData);191toEdge->addChildElement(edgeData);192edgeData->incRef("buildEdgeRelationData");193}194return true;195}196} else {197return writeErrorInvalidParent(SUMO_TAG_EDGEREL, SUMO_TAG_DATAINTERVAL);198}199} else {200return writeErrorInvalidParent(SUMO_TAG_EDGEREL, SUMO_TAG_DATASET);201}202}203204205bool206GNEDataHandler::buildTAZRelationData(const CommonXMLStructure::SumoBaseObject* sumoBaseObject, const std::string& fromTAZID,207const std::string& toTAZID, const Parameterised::Map& parameters) {208// get dataSet209GNEDataSet* dataSet = myNet->getAttributeCarriers()->retrieveDataSet(sumoBaseObject->getParentSumoBaseObject()->getStringAttribute(SUMO_ATTR_ID), false);210if (dataSet != nullptr) {211// get interval212GNEDataInterval* dataInterval = dataSet->retrieveInterval(213sumoBaseObject->getParentSumoBaseObject()->getDoubleAttribute(SUMO_ATTR_BEGIN),214sumoBaseObject->getParentSumoBaseObject()->getDoubleAttribute(SUMO_ATTR_END));215if (dataInterval != nullptr) {216// get from TAZs217GNEAdditional* fromTAZ = myNet->getAttributeCarriers()->retrieveAdditional(SUMO_TAG_TAZ, fromTAZID, false);218GNEAdditional* toTAZ = myNet->getAttributeCarriers()->retrieveAdditional(SUMO_TAG_TAZ, toTAZID, false);219if (fromTAZ == nullptr) {220return writeErrorInvalidParent(SUMO_TAG_TAZREL, SUMO_TAG_TAZ, fromTAZID);221} else if (toTAZ == nullptr) {222return writeErrorInvalidParent(SUMO_TAG_TAZREL, SUMO_TAG_TAZ, toTAZID);223} else if ((fromTAZ != toTAZ) && dataInterval->TAZRelExists(fromTAZ, toTAZ)) {224return writeError(TLF("There is already a TAZ rel defined between '%' and '%'.", fromTAZID, toTAZID));225} else if ((fromTAZ == toTAZ) && dataInterval->TAZRelExists(fromTAZ)) {226return writeError(TLF("There is already a TAZ rel defined in '%'.", toTAZID));227} else if (fromTAZ == toTAZ) {228GNEGenericData* edgeData = new GNETAZRelData(dataInterval, fromTAZ, parameters);229if (myAllowUndoRedo) {230myNet->getViewNet()->getUndoList()->begin(edgeData, TL("add TAZ rel"));231myNet->getViewNet()->getUndoList()->add(new GNEChange_GenericData(edgeData, true), true);232myNet->getViewNet()->getUndoList()->end();233} else {234dataInterval->addGenericDataChild(edgeData);235fromTAZ->addChildElement(edgeData);236edgeData->incRef("buildTAZRelationData");237}238return true;239} else {240GNEGenericData* edgeData = new GNETAZRelData(dataInterval, fromTAZ, toTAZ, parameters);241if (myAllowUndoRedo) {242myNet->getViewNet()->getUndoList()->begin(edgeData, TL("add TAZ rel"));243myNet->getViewNet()->getUndoList()->add(new GNEChange_GenericData(edgeData, true), true);244myNet->getViewNet()->getUndoList()->end();245} else {246dataInterval->addGenericDataChild(edgeData);247fromTAZ->addChildElement(edgeData);248toTAZ->addChildElement(edgeData);249edgeData->incRef("buildTAZRelationData");250}251return true;252}253} else {254return writeErrorInvalidParent(SUMO_TAG_TAZREL, SUMO_TAG_DATAINTERVAL);255}256} else {257return writeErrorInvalidParent(SUMO_TAG_TAZREL, SUMO_TAG_DATASET);258}259}260261262bool263GNEDataHandler::checkDuplicatedDataSet(const std::string& id) {264// retrieve data set265auto dataSet = myNet->getAttributeCarriers()->retrieveDataSet(id, false);266// if demand exist, check if overwrite (delete)267if (dataSet) {268if (myOverwriteElements) {269// delete data element (and all of their childrens)270myNet->deleteDataSet(dataSet, myNet->getViewNet()->getUndoList());271} else if (myRemainElements) {272// duplicated dataset273return writeWarningDuplicated(SUMO_TAG_DATASET, id, SUMO_TAG_DATASET);274} else {275// open overwrite dialog276GNEOverwriteElement overwriteElementDialog(this, dataSet);277// continue depending of result278if (overwriteElementDialog.getResult() == GNEOverwriteElement::Result::ACCEPT) {279// delete data element (and all of their childrens)280myNet->deleteDataSet(dataSet, myNet->getViewNet()->getUndoList());281} else if (overwriteElementDialog.getResult() == GNEOverwriteElement::Result::CANCEL) {282// duplicated dataset283return writeWarningDuplicated(SUMO_TAG_DATASET, id, SUMO_TAG_DATASET);284} else {285return false;286}287}288}289return true;290}291292/****************************************************************************/293294295