Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
eclipse
GitHub Repository: eclipse/sumo
Path: blob/main/src/netedit/elements/data/GNEMeanDataHandler.cpp
193735 views
1
/****************************************************************************/
2
// Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.dev/sumo
3
// Copyright (C) 2001-2026 German Aerospace Center (DLR) and others.
4
// This program and the accompanying materials are made available under the
5
// terms of the Eclipse Public License 2.0 which is available at
6
// https://www.eclipse.org/legal/epl-2.0/
7
// This Source Code may also be made available under the following Secondary
8
// Licenses when the conditions for such availability set forth in the Eclipse
9
// Public License 2.0 are satisfied: GNU General Public License, version 2
10
// or later which is available at
11
// https://www.gnu.org/licenses/old-licenses/gpl-2.0-standalone.html
12
// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later
13
/****************************************************************************/
14
/// @file GNEMeanDataHandler.cpp
15
/// @author Pablo Alvarez Lopez
16
/// @date Nov 22
17
///
18
// Builds meanData objects for netedit
19
/****************************************************************************/
20
21
#include <netedit/changes/GNEChange_MeanData.h>
22
#include <netedit/dialogs/basic/GNEOverwriteElement.h>
23
#include <netedit/elements/data/GNEMeanData.h>
24
#include <netedit/GNEApplicationWindow.h>
25
#include <netedit/GNENet.h>
26
#include <netedit/GNETagProperties.h>
27
#include <netedit/GNEUndoList.h>
28
#include <netedit/GNEViewNet.h>
29
#include <utils/gui/div/GUIDesigns.h>
30
31
#include "GNEMeanDataHandler.h"
32
33
// ===========================================================================
34
// member method definitions
35
// ===========================================================================
36
37
GNEMeanDataHandler::GNEMeanDataHandler(GNENet* net, FileBucket* fileBucket, const bool allowUndoRedo) :
38
MeanDataHandler(fileBucket),
39
myNet(net),
40
myAllowUndoRedo(allowUndoRedo) {
41
}
42
43
44
GNEMeanDataHandler::~GNEMeanDataHandler() {
45
// update options based in current buckets
46
myNet->getGNEApplicationWindow()->getFileBucketHandler()->updateOptions();
47
}
48
49
50
bool
51
GNEMeanDataHandler::buildEdgeMeanData(const CommonXMLStructure::SumoBaseObject* /*sumoBaseObject*/, const std::string& id,
52
const std::string& file, const std::string& type, const SUMOTime period, const SUMOTime begin,
53
const SUMOTime end, const bool trackVehicles, const std::vector<std::string>& writtenAttributes,
54
const bool aggregate, const std::vector<std::string>& edgeIDs, const std::string& edgeFile,
55
const std::string& excludeEmpty, const bool withInternal, const std::vector<std::string>& detectPersons,
56
const double minSamples, const double maxTravelTime, const std::vector<std::string>& vTypes,
57
const double speedThreshold) {
58
// parse attributes
59
const auto edges = parseEdges(SUMO_TAG_MEANDATA_EDGE, edgeIDs);
60
// parse edges
61
const auto attributes = parseAttributes(SUMO_TAG_MEANDATA_EDGE, writtenAttributes);
62
// check if meanData edge exists
63
if (!checkValidAdditionalID(SUMO_TAG_MEANDATA_EDGE, id)) {
64
return false;
65
} else if (!checkDuplicatedMeanDataElement(SUMO_TAG_MEANDATA_EDGE, id)) {
66
return false;
67
} else if ((period != TIME2STEPS(-1)) && !checkNegative(SUMO_TAG_MEANDATA_EDGE, id, SUMO_ATTR_PERIOD, period, true)) {
68
return false;
69
} else if ((begin != TIME2STEPS(-1)) && !checkNegative(SUMO_TAG_MEANDATA_EDGE, id, SUMO_ATTR_BEGIN, begin, true)) {
70
return false;
71
} else if ((end != TIME2STEPS(-1)) && !checkNegative(SUMO_TAG_MEANDATA_EDGE, id, SUMO_ATTR_END, end, true)) {
72
return false;
73
} else if (!checkNegative(SUMO_TAG_MEANDATA_EDGE, id, SUMO_ATTR_MAX_TRAVELTIME, maxTravelTime, true)) {
74
return false;
75
} else if (!checkNegative(SUMO_TAG_MEANDATA_EDGE, id, SUMO_ATTR_MIN_SAMPLES, minSamples, true)) {
76
return false;
77
} else if (!checkNegative(SUMO_TAG_MEANDATA_EDGE, id, SUMO_ATTR_HALTING_SPEED_THRESHOLD, speedThreshold, true)) {
78
return false;
79
} else if (!checkExcludeEmpty(SUMO_TAG_MEANDATA_EDGE, id, excludeEmpty)) {
80
return false;
81
} else if (!checkDetectPersons(SUMO_TAG_MEANDATA_EDGE, id, detectPersons)) {
82
return false;
83
} else if ((edges.size() == edgeIDs.size()) && (attributes.size() == writtenAttributes.size())) {
84
GNEMeanData* edgeMeanData = new GNEMeanData(SUMO_TAG_MEANDATA_EDGE, id, myNet, myFileBucket, file, type, period, begin, end,
85
trackVehicles, attributes, aggregate, edgeIDs, edgeFile, excludeEmpty, withInternal,
86
detectPersons, minSamples, maxTravelTime, vTypes, speedThreshold);
87
if (myAllowUndoRedo) {
88
myNet->getUndoList()->begin(edgeMeanData, TL("add meanDataEdge"));
89
myNet->getUndoList()->add(new GNEChange_MeanData(edgeMeanData, true), true);
90
myNet->getUndoList()->end();
91
} else {
92
myNet->getAttributeCarriers()->insertMeanData(edgeMeanData);
93
edgeMeanData->incRef("buildEdgeMeanData");
94
}
95
return true;
96
} else {
97
return false;
98
}
99
}
100
101
102
bool
103
GNEMeanDataHandler::buildLaneMeanData(const CommonXMLStructure::SumoBaseObject* /*sumoBaseObject*/, const std::string& id,
104
const std::string& file, const std::string& type, const SUMOTime period, const SUMOTime begin,
105
const SUMOTime end, const bool trackVehicles, const std::vector<std::string>& writtenAttributes,
106
const bool aggregate, const std::vector<std::string>& edgeIDs, const std::string& edgeFile,
107
const std::string& excludeEmpty, const bool withInternal, const std::vector<std::string>& detectPersons,
108
const double minSamples, const double maxTravelTime, const std::vector<std::string>& vTypes,
109
const double speedThreshold) {
110
// parse attributes
111
const auto edges = parseEdges(SUMO_TAG_MEANDATA_LANE, edgeIDs);
112
// parse edges
113
const auto attributes = parseAttributes(SUMO_TAG_MEANDATA_LANE, writtenAttributes);
114
// check if meanData edge exists
115
if (!checkValidAdditionalID(SUMO_TAG_MEANDATA_LANE, id)) {
116
return false;
117
} else if (!checkDuplicatedMeanDataElement(SUMO_TAG_MEANDATA_LANE, id)) {
118
return false;
119
} else if ((period != TIME2STEPS(-1)) && !checkNegative(SUMO_TAG_MEANDATA_LANE, id, SUMO_ATTR_PERIOD, period, true)) {
120
return false;
121
} else if ((begin != TIME2STEPS(-1)) && !checkNegative(SUMO_TAG_MEANDATA_LANE, id, SUMO_ATTR_BEGIN, begin, true)) {
122
return false;
123
} else if ((end != TIME2STEPS(-1)) && !checkNegative(SUMO_TAG_MEANDATA_LANE, id, SUMO_ATTR_END, end, true)) {
124
return false;
125
} else if (!checkNegative(SUMO_TAG_MEANDATA_LANE, id, SUMO_ATTR_MAX_TRAVELTIME, maxTravelTime, true)) {
126
return false;
127
} else if (!checkNegative(SUMO_TAG_MEANDATA_LANE, id, SUMO_ATTR_MIN_SAMPLES, minSamples, true)) {
128
return false;
129
} else if (!checkNegative(SUMO_TAG_MEANDATA_LANE, id, SUMO_ATTR_HALTING_SPEED_THRESHOLD, speedThreshold, true)) {
130
return false;
131
} else if (!checkExcludeEmpty(SUMO_TAG_MEANDATA_LANE, id, excludeEmpty)) {
132
return false;
133
} else if (!checkDetectPersons(SUMO_TAG_MEANDATA_LANE, id, detectPersons)) {
134
return false;
135
} else if ((edges.size() == edgeIDs.size()) && (attributes.size() == writtenAttributes.size())) {
136
GNEMeanData* edgeMeanData = new GNEMeanData(SUMO_TAG_MEANDATA_LANE, id, myNet, myFileBucket, file, type, period, begin, end,
137
trackVehicles, attributes, aggregate, edgeIDs, edgeFile, excludeEmpty, withInternal,
138
detectPersons, minSamples, maxTravelTime, vTypes, speedThreshold);
139
if (myAllowUndoRedo) {
140
myNet->getUndoList()->begin(edgeMeanData, TL("add meanDataLane"));
141
myNet->getUndoList()->add(new GNEChange_MeanData(edgeMeanData, true), true);
142
myNet->getUndoList()->end();
143
} else {
144
myNet->getAttributeCarriers()->insertMeanData(edgeMeanData);
145
edgeMeanData->incRef("buildEdgeMeanData");
146
}
147
return true;
148
} else {
149
return false;
150
}
151
}
152
153
154
std::vector<GNEEdge*>
155
GNEMeanDataHandler::parseEdges(const SumoXMLTag tag, const std::vector<std::string>& edgeIDs) {
156
std::vector<GNEEdge*> edges;
157
for (const auto& edgeID : edgeIDs) {
158
GNEEdge* edge = myNet->getAttributeCarriers()->retrieveEdge(edgeID, false);
159
// empty edges aren't allowed. If edge is empty, write error, clear edges and stop
160
if (edge == nullptr) {
161
writeError(TLF("Could not build % in netedit", toString(tag)) + std::string("; ") + TL("Edge doesn't exist."));
162
edges.clear();
163
return edges;
164
} else {
165
edges.push_back(edge);
166
}
167
}
168
return edges;
169
}
170
171
172
std::vector<SumoXMLAttr>
173
GNEMeanDataHandler::parseAttributes(const SumoXMLTag tag, const std::vector<std::string>& attrStrs) {
174
std::vector<SumoXMLAttr> attrs;
175
for (const auto& attrStr : attrStrs) {
176
if (SUMOXMLDefinitions::Attrs.hasString(attrStr)) {
177
attrs.push_back(static_cast<SumoXMLAttr>(SUMOXMLDefinitions::Attrs.get(attrStr)));
178
} else {
179
writeError(TLF("Could not build % in netedit", toString(tag)) + std::string("; ") + TLF("Attribute '%' doesn't exist.", attrStr));
180
attrs.clear();
181
return attrs;
182
}
183
}
184
return attrs;
185
}
186
187
188
bool
189
GNEMeanDataHandler::checkDuplicatedMeanDataElement(const SumoXMLTag tag, const std::string& id) {
190
// retrieve meanData element
191
auto meanDataElement = myNet->getAttributeCarriers()->retrieveMeanData(tag, id, false);
192
// if meanData exist, check if overwrite (delete)
193
if (meanDataElement) {
194
if (myOverwriteElements) {
195
// delete meanData element (and all of their childrens)
196
myNet->deleteMeanData(meanDataElement, myNet->getUndoList());
197
} else if (myRemainElements) {
198
// duplicated dataset
199
return writeWarningDuplicated(tag, meanDataElement->getID(), meanDataElement->getTagProperty()->getTag());
200
} else {
201
// open overwrite dialog
202
GNEOverwriteElement overwriteElementDialog(this, meanDataElement);
203
// continue depending of result
204
if (overwriteElementDialog.getResult() == GNEOverwriteElement::Result::ACCEPT) {
205
// delete meanData element (and all of their childrens)
206
myNet->deleteMeanData(meanDataElement, myNet->getUndoList());
207
} else if (overwriteElementDialog.getResult() == GNEOverwriteElement::Result::CANCEL) {
208
// duplicated demand
209
return writeWarningDuplicated(tag, meanDataElement->getID(), meanDataElement->getTagProperty()->getTag());
210
} else {
211
return false;
212
}
213
}
214
}
215
return true;
216
}
217
218
219
bool
220
GNEMeanDataHandler::checkExcludeEmpty(const SumoXMLTag tag, const std::string& id, const std::string& excludeEmpty) {
221
if (GNEAttributeCarrier::canParse<bool>(excludeEmpty)) {
222
return true;
223
} else if (excludeEmpty == SUMOXMLDefinitions::ExcludeEmptys.getString(ExcludeEmpty::DEFAULTS)) {
224
return true;
225
} else {
226
return writeError(TLF("Could not build % with ID '%' in netedit; Invalid value '%' for %.", toString(tag), id, excludeEmpty, toString(SUMO_ATTR_EXCLUDE_EMPTY)));
227
}
228
}
229
230
231
bool
232
GNEMeanDataHandler::checkDetectPersons(const SumoXMLTag tag, const std::string& id, const std::vector<std::string>& detectPersons) {
233
// check all values
234
for (const auto& detectPerson : detectPersons) {
235
if (!SUMOXMLDefinitions::PersonModeValues.hasString(detectPerson)) {
236
return writeError(TLF("Could not build % with ID '%' in netedit; Invalid value '%' for %.", toString(tag), id, detectPerson, toString(SUMO_ATTR_DETECT_PERSONS)));
237
}
238
}
239
return true;
240
}
241
242
/****************************************************************************/
243
244