Path: blob/main/src/netedit/elements/data/GNEMeanDataHandler.cpp
193735 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 GNEMeanDataHandler.cpp14/// @author Pablo Alvarez Lopez15/// @date Nov 2216///17// Builds meanData objects for netedit18/****************************************************************************/1920#include <netedit/changes/GNEChange_MeanData.h>21#include <netedit/dialogs/basic/GNEOverwriteElement.h>22#include <netedit/elements/data/GNEMeanData.h>23#include <netedit/GNEApplicationWindow.h>24#include <netedit/GNENet.h>25#include <netedit/GNETagProperties.h>26#include <netedit/GNEUndoList.h>27#include <netedit/GNEViewNet.h>28#include <utils/gui/div/GUIDesigns.h>2930#include "GNEMeanDataHandler.h"3132// ===========================================================================33// member method definitions34// ===========================================================================3536GNEMeanDataHandler::GNEMeanDataHandler(GNENet* net, FileBucket* fileBucket, const bool allowUndoRedo) :37MeanDataHandler(fileBucket),38myNet(net),39myAllowUndoRedo(allowUndoRedo) {40}414243GNEMeanDataHandler::~GNEMeanDataHandler() {44// update options based in current buckets45myNet->getGNEApplicationWindow()->getFileBucketHandler()->updateOptions();46}474849bool50GNEMeanDataHandler::buildEdgeMeanData(const CommonXMLStructure::SumoBaseObject* /*sumoBaseObject*/, const std::string& id,51const std::string& file, const std::string& type, const SUMOTime period, const SUMOTime begin,52const SUMOTime end, const bool trackVehicles, const std::vector<std::string>& writtenAttributes,53const bool aggregate, const std::vector<std::string>& edgeIDs, const std::string& edgeFile,54const std::string& excludeEmpty, const bool withInternal, const std::vector<std::string>& detectPersons,55const double minSamples, const double maxTravelTime, const std::vector<std::string>& vTypes,56const double speedThreshold) {57// parse attributes58const auto edges = parseEdges(SUMO_TAG_MEANDATA_EDGE, edgeIDs);59// parse edges60const auto attributes = parseAttributes(SUMO_TAG_MEANDATA_EDGE, writtenAttributes);61// check if meanData edge exists62if (!checkValidAdditionalID(SUMO_TAG_MEANDATA_EDGE, id)) {63return false;64} else if (!checkDuplicatedMeanDataElement(SUMO_TAG_MEANDATA_EDGE, id)) {65return false;66} else if ((period != TIME2STEPS(-1)) && !checkNegative(SUMO_TAG_MEANDATA_EDGE, id, SUMO_ATTR_PERIOD, period, true)) {67return false;68} else if ((begin != TIME2STEPS(-1)) && !checkNegative(SUMO_TAG_MEANDATA_EDGE, id, SUMO_ATTR_BEGIN, begin, true)) {69return false;70} else if ((end != TIME2STEPS(-1)) && !checkNegative(SUMO_TAG_MEANDATA_EDGE, id, SUMO_ATTR_END, end, true)) {71return false;72} else if (!checkNegative(SUMO_TAG_MEANDATA_EDGE, id, SUMO_ATTR_MAX_TRAVELTIME, maxTravelTime, true)) {73return false;74} else if (!checkNegative(SUMO_TAG_MEANDATA_EDGE, id, SUMO_ATTR_MIN_SAMPLES, minSamples, true)) {75return false;76} else if (!checkNegative(SUMO_TAG_MEANDATA_EDGE, id, SUMO_ATTR_HALTING_SPEED_THRESHOLD, speedThreshold, true)) {77return false;78} else if (!checkExcludeEmpty(SUMO_TAG_MEANDATA_EDGE, id, excludeEmpty)) {79return false;80} else if (!checkDetectPersons(SUMO_TAG_MEANDATA_EDGE, id, detectPersons)) {81return false;82} else if ((edges.size() == edgeIDs.size()) && (attributes.size() == writtenAttributes.size())) {83GNEMeanData* edgeMeanData = new GNEMeanData(SUMO_TAG_MEANDATA_EDGE, id, myNet, myFileBucket, file, type, period, begin, end,84trackVehicles, attributes, aggregate, edgeIDs, edgeFile, excludeEmpty, withInternal,85detectPersons, minSamples, maxTravelTime, vTypes, speedThreshold);86if (myAllowUndoRedo) {87myNet->getUndoList()->begin(edgeMeanData, TL("add meanDataEdge"));88myNet->getUndoList()->add(new GNEChange_MeanData(edgeMeanData, true), true);89myNet->getUndoList()->end();90} else {91myNet->getAttributeCarriers()->insertMeanData(edgeMeanData);92edgeMeanData->incRef("buildEdgeMeanData");93}94return true;95} else {96return false;97}98}99100101bool102GNEMeanDataHandler::buildLaneMeanData(const CommonXMLStructure::SumoBaseObject* /*sumoBaseObject*/, const std::string& id,103const std::string& file, const std::string& type, const SUMOTime period, const SUMOTime begin,104const SUMOTime end, const bool trackVehicles, const std::vector<std::string>& writtenAttributes,105const bool aggregate, const std::vector<std::string>& edgeIDs, const std::string& edgeFile,106const std::string& excludeEmpty, const bool withInternal, const std::vector<std::string>& detectPersons,107const double minSamples, const double maxTravelTime, const std::vector<std::string>& vTypes,108const double speedThreshold) {109// parse attributes110const auto edges = parseEdges(SUMO_TAG_MEANDATA_LANE, edgeIDs);111// parse edges112const auto attributes = parseAttributes(SUMO_TAG_MEANDATA_LANE, writtenAttributes);113// check if meanData edge exists114if (!checkValidAdditionalID(SUMO_TAG_MEANDATA_LANE, id)) {115return false;116} else if (!checkDuplicatedMeanDataElement(SUMO_TAG_MEANDATA_LANE, id)) {117return false;118} else if ((period != TIME2STEPS(-1)) && !checkNegative(SUMO_TAG_MEANDATA_LANE, id, SUMO_ATTR_PERIOD, period, true)) {119return false;120} else if ((begin != TIME2STEPS(-1)) && !checkNegative(SUMO_TAG_MEANDATA_LANE, id, SUMO_ATTR_BEGIN, begin, true)) {121return false;122} else if ((end != TIME2STEPS(-1)) && !checkNegative(SUMO_TAG_MEANDATA_LANE, id, SUMO_ATTR_END, end, true)) {123return false;124} else if (!checkNegative(SUMO_TAG_MEANDATA_LANE, id, SUMO_ATTR_MAX_TRAVELTIME, maxTravelTime, true)) {125return false;126} else if (!checkNegative(SUMO_TAG_MEANDATA_LANE, id, SUMO_ATTR_MIN_SAMPLES, minSamples, true)) {127return false;128} else if (!checkNegative(SUMO_TAG_MEANDATA_LANE, id, SUMO_ATTR_HALTING_SPEED_THRESHOLD, speedThreshold, true)) {129return false;130} else if (!checkExcludeEmpty(SUMO_TAG_MEANDATA_LANE, id, excludeEmpty)) {131return false;132} else if (!checkDetectPersons(SUMO_TAG_MEANDATA_LANE, id, detectPersons)) {133return false;134} else if ((edges.size() == edgeIDs.size()) && (attributes.size() == writtenAttributes.size())) {135GNEMeanData* edgeMeanData = new GNEMeanData(SUMO_TAG_MEANDATA_LANE, id, myNet, myFileBucket, file, type, period, begin, end,136trackVehicles, attributes, aggregate, edgeIDs, edgeFile, excludeEmpty, withInternal,137detectPersons, minSamples, maxTravelTime, vTypes, speedThreshold);138if (myAllowUndoRedo) {139myNet->getUndoList()->begin(edgeMeanData, TL("add meanDataLane"));140myNet->getUndoList()->add(new GNEChange_MeanData(edgeMeanData, true), true);141myNet->getUndoList()->end();142} else {143myNet->getAttributeCarriers()->insertMeanData(edgeMeanData);144edgeMeanData->incRef("buildEdgeMeanData");145}146return true;147} else {148return false;149}150}151152153std::vector<GNEEdge*>154GNEMeanDataHandler::parseEdges(const SumoXMLTag tag, const std::vector<std::string>& edgeIDs) {155std::vector<GNEEdge*> edges;156for (const auto& edgeID : edgeIDs) {157GNEEdge* edge = myNet->getAttributeCarriers()->retrieveEdge(edgeID, false);158// empty edges aren't allowed. If edge is empty, write error, clear edges and stop159if (edge == nullptr) {160writeError(TLF("Could not build % in netedit", toString(tag)) + std::string("; ") + TL("Edge doesn't exist."));161edges.clear();162return edges;163} else {164edges.push_back(edge);165}166}167return edges;168}169170171std::vector<SumoXMLAttr>172GNEMeanDataHandler::parseAttributes(const SumoXMLTag tag, const std::vector<std::string>& attrStrs) {173std::vector<SumoXMLAttr> attrs;174for (const auto& attrStr : attrStrs) {175if (SUMOXMLDefinitions::Attrs.hasString(attrStr)) {176attrs.push_back(static_cast<SumoXMLAttr>(SUMOXMLDefinitions::Attrs.get(attrStr)));177} else {178writeError(TLF("Could not build % in netedit", toString(tag)) + std::string("; ") + TLF("Attribute '%' doesn't exist.", attrStr));179attrs.clear();180return attrs;181}182}183return attrs;184}185186187bool188GNEMeanDataHandler::checkDuplicatedMeanDataElement(const SumoXMLTag tag, const std::string& id) {189// retrieve meanData element190auto meanDataElement = myNet->getAttributeCarriers()->retrieveMeanData(tag, id, false);191// if meanData exist, check if overwrite (delete)192if (meanDataElement) {193if (myOverwriteElements) {194// delete meanData element (and all of their childrens)195myNet->deleteMeanData(meanDataElement, myNet->getUndoList());196} else if (myRemainElements) {197// duplicated dataset198return writeWarningDuplicated(tag, meanDataElement->getID(), meanDataElement->getTagProperty()->getTag());199} else {200// open overwrite dialog201GNEOverwriteElement overwriteElementDialog(this, meanDataElement);202// continue depending of result203if (overwriteElementDialog.getResult() == GNEOverwriteElement::Result::ACCEPT) {204// delete meanData element (and all of their childrens)205myNet->deleteMeanData(meanDataElement, myNet->getUndoList());206} else if (overwriteElementDialog.getResult() == GNEOverwriteElement::Result::CANCEL) {207// duplicated demand208return writeWarningDuplicated(tag, meanDataElement->getID(), meanDataElement->getTagProperty()->getTag());209} else {210return false;211}212}213}214return true;215}216217218bool219GNEMeanDataHandler::checkExcludeEmpty(const SumoXMLTag tag, const std::string& id, const std::string& excludeEmpty) {220if (GNEAttributeCarrier::canParse<bool>(excludeEmpty)) {221return true;222} else if (excludeEmpty == SUMOXMLDefinitions::ExcludeEmptys.getString(ExcludeEmpty::DEFAULTS)) {223return true;224} else {225return writeError(TLF("Could not build % with ID '%' in netedit; Invalid value '%' for %.", toString(tag), id, excludeEmpty, toString(SUMO_ATTR_EXCLUDE_EMPTY)));226}227}228229230bool231GNEMeanDataHandler::checkDetectPersons(const SumoXMLTag tag, const std::string& id, const std::vector<std::string>& detectPersons) {232// check all values233for (const auto& detectPerson : detectPersons) {234if (!SUMOXMLDefinitions::PersonModeValues.hasString(detectPerson)) {235return writeError(TLF("Could not build % with ID '%' in netedit; Invalid value '%' for %.", toString(tag), id, detectPerson, toString(SUMO_ATTR_DETECT_PERSONS)));236}237}238return true;239}240241/****************************************************************************/242243244