Path: blob/main/src/netedit/elements/data/GNEDataSet.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 GNEDataSet.cpp14/// @author Pablo Alvarez Lopez15/// @date Jan 202016///17// A abstract class for data sets18/****************************************************************************/1920#include <netedit/GNENet.h>21#include <netedit/GNEViewParent.h>22#include <netedit/changes/GNEChange_Attribute.h>23#include <netedit/frames/common/GNEInspectorFrame.h>24#include <netedit/frames/GNEElementTree.h>2526#include "GNEDataSet.h"27#include "GNEDataInterval.h"2829// ===========================================================================30// member method definitions31// ===========================================================================3233// ---------------------------------------------------------------------------34// GNEDataSet::AttributeColors - methods35// ---------------------------------------------------------------------------3637GNEDataSet::AttributeColors::AttributeColors() {38}394041void42GNEDataSet::AttributeColors::updateValues(const std::string& attribute, const double value) {43// check if exist44if (myMinMaxValue.count(attribute) == 0) {45myMinMaxValue[attribute] = std::make_pair(value, value);46} else {47// update min value48if (value < myMinMaxValue.at(attribute).first) {49myMinMaxValue.at(attribute).first = value;50}51// update max value52if (value > myMinMaxValue.at(attribute).second) {53myMinMaxValue.at(attribute).second = value;54}55}56}575859void60GNEDataSet::AttributeColors::updateAllValues(const AttributeColors& attributeColors) {61// iterate over map62for (const auto& attributeColor : attributeColors.myMinMaxValue) {63if (myMinMaxValue.count(attributeColor.first) == 0) {64myMinMaxValue[attributeColor.first] = attributeColor.second;65} else {66// update min value67if (attributeColor.second.first < myMinMaxValue.at(attributeColor.first).first) {68myMinMaxValue.at(attributeColor.first).first = attributeColor.second.first;69}70// update max value71if (attributeColor.second.second > myMinMaxValue.at(attributeColor.first).second) {72myMinMaxValue.at(attributeColor.first).second = attributeColor.second.second;73}74}75}76}777879bool80GNEDataSet::AttributeColors::exist(const std::string& attribute) const {81return (myMinMaxValue.count(attribute) > 0);82}838485double86GNEDataSet::AttributeColors::getMinValue(const std::string& attribute) const {87return myMinMaxValue.at(attribute).first;88}899091double92GNEDataSet::AttributeColors::getMaxValue(const std::string& attribute) const {93return myMinMaxValue.at(attribute).second;94}959697void98GNEDataSet::AttributeColors::clear() {99myMinMaxValue.clear();100}101102// ---------------------------------------------------------------------------103// GNEDataSet - methods104// ---------------------------------------------------------------------------105106GNEDataSet::GNEDataSet(const std::string& dataSetID, GNENet* net, const std::string& filename) :107GNEAttributeCarrier(SUMO_TAG_DATASET, net, filename, false),108myDataSetID(dataSetID) {109}110111112GNEDataSet::~GNEDataSet() {}113114115GNEHierarchicalElement*116GNEDataSet::getHierarchicalElement() {117return this;118}119120121GUIGlObject*122GNEDataSet::getGUIGlObject() {123return nullptr;124}125126127const GUIGlObject*128GNEDataSet::getGUIGlObject() const {129return nullptr;130}131132133void134GNEDataSet::updateAttributeColors() {135// first update attribute colors in data interval childrens136for (const auto& interval : myDataIntervalChildren) {137interval.second->updateAttributeColors();138}139// continue with data sets containers140myAllAttributeColors.clear();141mySpecificAttributeColors.clear();142// iterate over all data interval children143for (const auto& interval : myDataIntervalChildren) {144myAllAttributeColors.updateAllValues(interval.second->getAllAttributeColors());145}146// iterate over specificdata interval children147for (const auto& interval : myDataIntervalChildren) {148for (const auto& specificAttributeColor : interval.second->getSpecificAttributeColors()) {149mySpecificAttributeColors[specificAttributeColor.first].updateAllValues(specificAttributeColor.second);150}151}152}153154155const GNEDataSet::AttributeColors&156GNEDataSet::getAllAttributeColors() const {157return myAllAttributeColors;158}159160161const std::map<SumoXMLTag, GNEDataSet::AttributeColors>&162GNEDataSet::getSpecificAttributeColors() const {163return mySpecificAttributeColors;164}165166167void168GNEDataSet::updateGeometry() {169// nothing to update170}171172173Position174GNEDataSet::getPositionInView() const {175return Position(0, 0);176}177178179void180GNEDataSet::writeDataSet(OutputDevice& device) const {181// iterate over intervals182for (const auto& interval : myDataIntervalChildren) {183// open device184device.openTag(SUMO_TAG_INTERVAL);185// write ID186device.writeAttr(SUMO_ATTR_ID, getID());187// write begin188device.writeAttr(SUMO_ATTR_BEGIN, interval.second->getAttribute(SUMO_ATTR_BEGIN));189// write end190device.writeAttr(SUMO_ATTR_END, interval.second->getAttribute(SUMO_ATTR_END));191// iterate over interval generic datas192for (const auto& genericData : interval.second->getGenericDataChildren()) {193// write generic data194genericData->writeGenericData(device);195}196// close device197device.closeTag();198}199}200201202bool203GNEDataSet::checkDrawFromContour() const {204return false;205}206207208bool209GNEDataSet::checkDrawToContour() const {210return false;211}212213214bool215GNEDataSet::checkDrawRelatedContour() const {216return false;217}218219220bool221GNEDataSet::checkDrawOverContour() const {222return false;223}224225226bool227GNEDataSet::checkDrawDeleteContour() const {228return false;229}230231232bool233GNEDataSet::checkDrawDeleteContourSmall() const {234return false;235}236237238bool239GNEDataSet::checkDrawSelectContour() const {240return false;241}242243244bool245GNEDataSet::checkDrawMoveContour() const {246return false;247}248249250void251GNEDataSet::addDataIntervalChild(GNEDataInterval* dataInterval) {252// check that dataInterval wasn't previously inserted253if (myDataIntervalChildren.count(dataInterval->getAttributeDouble(SUMO_ATTR_BEGIN)) == 0) {254// add data interval child255myDataIntervalChildren[dataInterval->getAttributeDouble(SUMO_ATTR_BEGIN)] = dataInterval;256// add reference in attributeCarriers257myNet->getAttributeCarriers()->insertDataInterval(dataInterval, dataInterval);258} else {259throw ProcessError(TL("DataInterval was already inserted"));260}261}262263264void265GNEDataSet::removeDataIntervalChild(GNEDataInterval* dataInterval) {266// check that dataInterval was previously inserted267if (myDataIntervalChildren.count(dataInterval->getAttributeDouble(SUMO_ATTR_BEGIN)) == 1) {268// remove data interval child269myDataIntervalChildren.erase(dataInterval->getAttributeDouble(SUMO_ATTR_BEGIN));270// remove it from inspected elements and GNEElementTree271myNet->getViewNet()->getInspectedElements().uninspectAC(dataInterval);272myNet->getViewNet()->getViewParent()->getInspectorFrame()->getHierarchicalElementTree()->removeCurrentEditedAttributeCarrier(dataInterval);273// remove reference from attributeCarriers274myNet->getAttributeCarriers()->deleteDataInterval(dataInterval);275} else {276throw ProcessError(TL("DataInterval wasn't previously inserted"));277}278}279280281bool282GNEDataSet::dataIntervalChildrenExist(GNEDataInterval* dataInterval) const {283for (const auto& interval : myDataIntervalChildren) {284if (interval.second == dataInterval) {285return true;286}287}288return false;289}290291void292GNEDataSet::updateDataIntervalBegin(const double oldBegin) {293// check that dataInterval was previously inserted294if (myDataIntervalChildren.count(oldBegin) == 1) {295// get data interval296GNEDataInterval* dataInterval = myDataIntervalChildren.at(oldBegin);297// insert again using new begin298myDataIntervalChildren[dataInterval->getAttributeDouble(SUMO_ATTR_BEGIN)] = dataInterval;299} else {300throw ProcessError(TL("DataInterval wasn't previously inserted"));301}302}303304305bool306GNEDataSet::checkNewInterval(const double newBegin, const double newEnd) {307return checkNewInterval(myDataIntervalChildren, newBegin, newEnd);308}309310311bool312GNEDataSet::checkNewBeginEnd(const GNEDataInterval* dataInterval, const double newBegin, const double newEnd) {313// make a copy of myDataIntervalChildren without dataInterval, and check checkNewInterval314std::map<const double, GNEDataInterval*> copyOfDataIntervalMap;315for (const auto& element : myDataIntervalChildren) {316if (element.second != dataInterval) {317copyOfDataIntervalMap.insert(element);318}319}320return checkNewInterval(copyOfDataIntervalMap, newBegin, newEnd);321}322323324GNEDataInterval*325GNEDataSet::retrieveInterval(const double begin, const double end) const {326if (myDataIntervalChildren.count(begin) == 0) {327return nullptr;328} else if (myDataIntervalChildren.at(begin)->getAttributeDouble(SUMO_ATTR_END) != end) {329return nullptr;330} else {331return myDataIntervalChildren.at(begin);332}333}334335336const std::map<const double, GNEDataInterval*>&337GNEDataSet::getDataIntervalChildren() const {338return myDataIntervalChildren;339}340341342std::string343GNEDataSet::getAttribute(SumoXMLAttr key) const {344switch (key) {345case SUMO_ATTR_ID:346return myDataSetID;347default:348return getCommonAttribute(this, key);349}350}351352353double354GNEDataSet::getAttributeDouble(SumoXMLAttr key) const {355throw InvalidArgument(getTagStr() + " doesn't have a double attribute of type '" + toString(key) + "'");356}357358359void360GNEDataSet::setAttribute(SumoXMLAttr key, const std::string& value, GNEUndoList* undoList) {361switch (key) {362case SUMO_ATTR_ID:363GNEChange_Attribute::changeAttribute(this, key, value, undoList);364break;365default:366setCommonAttribute(key, value, undoList);367break;368}369}370371372bool373GNEDataSet::isValid(SumoXMLAttr key, const std::string& value) {374switch (key) {375case SUMO_ATTR_ID:376if (SUMOXMLDefinitions::isValidNetID(value) && (myNet->getAttributeCarriers()->retrieveDataSet(value, false) == nullptr)) {377return true;378} else {379return false;380}381default:382return isCommonValid(key, value);383}384}385386387std::string388GNEDataSet::getPopUpID() const {389return getTagStr();390}391392393std::string394GNEDataSet::getHierarchyName() const {395return getTagStr() + ": " + myDataSetID;396}397398399const Parameterised::Map&400GNEDataSet::getACParametersMap() const {401return getParametersMap();402}403404405void406GNEDataSet::setAttribute(SumoXMLAttr key, const std::string& value) {407switch (key) {408case SUMO_ATTR_ID:409myDataSetID = value;410// update all intervals411for (const auto& interval : myDataIntervalChildren) {412interval.second->updateGenericDataIDs();413}414break;415default:416setCommonAttribute(this, key, value);417break;418}419// mark interval toolbar for update420myNet->getViewNet()->getIntervalBar().markForUpdate();421}422423424bool425GNEDataSet::checkNewInterval(const std::map<const double, GNEDataInterval*>& dataIntervalMap, const double newBegin, const double newEnd) {426if (dataIntervalMap.empty()) {427return true;428} else {429// declare first and last element430const auto itFirstElement = dataIntervalMap.begin();431const auto itLastElement = dataIntervalMap.rbegin();432if (newBegin > newEnd) {433return false;434} else if (dataIntervalMap.count(newBegin) == 1) {435return false;436} else if (newBegin < itFirstElement->first) {437return (newEnd <= itFirstElement->first);438} else if (newBegin > itLastElement->first) {439return (newBegin >= itLastElement->second->getAttributeDouble(SUMO_ATTR_END));440} else {441// iterate over myDataIntervalChildren442for (auto it = itFirstElement; it != dataIntervalMap.end(); it++) {443if (newBegin < it->first) {444// obtain previous edge445auto itPrevious = it;446itPrevious--;447// check overlapping with end448if (itPrevious->second->getAttributeDouble(SUMO_ATTR_END) < newBegin) {449return true;450}451}452}453}454return false;455}456}457458/****************************************************************************/459460461