Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
eclipse
GitHub Repository: eclipse/sumo
Path: blob/main/src/netedit/elements/data/GNEEdgeRelData.cpp
169684 views
1
/****************************************************************************/
2
// Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.dev/sumo
3
// Copyright (C) 2001-2025 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 GNEEdgeRelData.cpp
15
/// @author Pablo Alvarez Lopez
16
/// @date Jan 2020
17
///
18
// class for edge relation data
19
/****************************************************************************/
20
21
#include <netedit/GNENet.h>
22
#include <netedit/GNETagProperties.h>
23
#include <netedit/GNESegment.h>
24
#include <netedit/GNEUndoList.h>
25
#include <netedit/GNEViewNet.h>
26
#include <netedit/GNEViewParent.h>
27
#include <netedit/changes/GNEChange_Attribute.h>
28
#include <netedit/frames/data/GNEEdgeRelDataFrame.h>
29
#include <utils/gui/div/GLHelper.h>
30
#include <utils/gui/globjects/GLIncludes.h>
31
32
#include "GNEEdgeRelData.h"
33
#include "GNEDataInterval.h"
34
35
// ===========================================================================
36
// member method definitions
37
// ===========================================================================
38
39
GNEEdgeRelData::GNEEdgeRelData(GNENet* net) :
40
GNEGenericData(SUMO_TAG_EDGEREL, net) {
41
}
42
43
44
GNEEdgeRelData::GNEEdgeRelData(GNEDataInterval* dataIntervalParent, GNEEdge* fromEdge, GNEEdge* toEdge,
45
const Parameterised::Map& parameters) :
46
GNEGenericData(SUMO_TAG_EDGEREL, dataIntervalParent, parameters) {
47
// set parents
48
setParents<GNEEdge*>({fromEdge, toEdge});
49
}
50
51
52
GNEEdgeRelData::~GNEEdgeRelData() {}
53
54
55
RGBColor
56
GNEEdgeRelData::setColor(const GUIVisualizationSettings& s) const {
57
// set default color
58
RGBColor col = RGBColor::GREEN;
59
if (isAttributeCarrierSelected()) {
60
col = s.colorSettings.selectedEdgeDataColor;
61
} else if (s.dataColorer.getScheme().getName() == GUIVisualizationSettings::SCHEME_NAME_DATA_ATTRIBUTE_NUMERICAL) {
62
// user defined rainbow
63
double val = getColorValue(s, s.dataColorer.getActive());
64
col = s.dataColorer.getScheme().getColor(val);
65
} else if (myNet->getViewNet()->getEditModes().dataEditMode == DataEditMode::DATA_EDGERELDATA) {
66
// get selected data interval and filtered attribute
67
const GNEDataInterval* dataInterval = myNet->getViewNet()->getViewParent()->getEdgeRelDataFrame()->getIntervalSelector()->getDataInterval();
68
const std::string filteredAttribute = myNet->getViewNet()->getViewParent()->getEdgeRelDataFrame()->getAttributeSelector()->getFilteredAttribute();
69
// continue if there is a selected data interval and filtered attribute
70
if (dataInterval && (filteredAttribute.size() > 0)) {
71
// obtain minimum and maximum value
72
const double minValue = dataInterval->getSpecificAttributeColors().at(myTagProperty->getTag()).getMinValue(filteredAttribute);
73
const double maxValue = dataInterval->getSpecificAttributeColors().at(myTagProperty->getTag()).getMaxValue(filteredAttribute);
74
// get value
75
const double value = parse<double>(getParameter(filteredAttribute, "0"));
76
col = GNEViewNetHelper::getRainbowScaledColor(minValue, maxValue, value);
77
}
78
}
79
return col;
80
}
81
82
83
double
84
GNEEdgeRelData::getColorValue(const GUIVisualizationSettings& s, int activeScheme) const {
85
switch (activeScheme) {
86
case 0:
87
return 0;
88
case 1:
89
return isAttributeCarrierSelected();
90
case 2:
91
return 0; // setfunctional color const GNEAdditional* TAZA = getParentAdditionals().front();
92
case 3:
93
return 0; // setfunctional color const GNEAdditional* TAZA = getParentAdditionals().back();
94
case 4:
95
// by numerical attribute value
96
try {
97
if (hasParameter(s.relDataAttr)) {
98
return StringUtils::toDouble(getParameter(s.relDataAttr, "-1"));
99
} else {
100
return GUIVisualizationSettings::MISSING_DATA;
101
}
102
} catch (NumberFormatException&) {
103
return GUIVisualizationSettings::MISSING_DATA;
104
}
105
}
106
return 0;
107
}
108
109
110
bool
111
GNEEdgeRelData::isGenericDataVisible() const {
112
// obtain pointer to edge data frame (only for code legibly)
113
const GNEEdgeRelDataFrame* edgeRelDataFrame = myNet->getViewNet()->getViewParent()->getEdgeRelDataFrame();
114
// get current data edit mode
115
DataEditMode dataMode = myNet->getViewNet()->getEditModes().dataEditMode;
116
// check if we have to filter generic data
117
if ((dataMode == DataEditMode::DATA_INSPECT) || (dataMode == DataEditMode::DATA_DELETE) || (dataMode == DataEditMode::DATA_SELECT)) {
118
return isVisibleInspectDeleteSelect();
119
} else if (edgeRelDataFrame->shown()) {
120
// check interval
121
if ((edgeRelDataFrame->getIntervalSelector()->getDataInterval() != nullptr) &&
122
(edgeRelDataFrame->getIntervalSelector()->getDataInterval() != myDataIntervalParent)) {
123
return false;
124
}
125
// check attribute
126
if ((edgeRelDataFrame->getAttributeSelector()->getFilteredAttribute().size() > 0) &&
127
(getParametersMap().count(edgeRelDataFrame->getAttributeSelector()->getFilteredAttribute()) == 0)) {
128
return false;
129
}
130
// all checks ok, then return true
131
return true;
132
} else {
133
// GNEEdgeRelDataFrame hidden, then return false
134
return false;
135
}
136
}
137
138
139
void
140
GNEEdgeRelData::updateGeometry() {
141
// just compute path
142
computePathElement();
143
}
144
145
146
void
147
GNEEdgeRelData::drawGL(const GUIVisualizationSettings& /*s*/) const {
148
// Nothing to draw
149
}
150
151
152
void
153
GNEEdgeRelData::computePathElement() {
154
// calculate path
155
myNet->getDataPathManager()->calculateConsecutivePathEdges(this, SVC_IGNORING, getParentEdges());
156
}
157
158
159
void
160
GNEEdgeRelData::drawLanePartialGL(const GUIVisualizationSettings& s, const GNESegment* segment, const double offsetFront) const {
161
// get color
162
const auto color = setColor(s);
163
if (segment->getLane() && (color.alpha() != 0) && myNet->getViewNet()->getEditModes().isCurrentSupermodeData()) {
164
// get detail level
165
const auto d = s.getDetailLevel(1);
166
// draw over all edge's lanes
167
for (const auto& laneEdge : segment->getLane()->getParentEdge()->getChildLanes()) {
168
// get lane width
169
const double laneWidth = s.addSize.getExaggeration(s, laneEdge) * s.edgeRelWidthExaggeration *
170
(laneEdge->getParentEdge()->getNBEdge()->getLaneWidth(laneEdge->getIndex()) * 0.5);
171
// Add a draw matrix
172
GLHelper::pushMatrix();
173
// Start with the drawing of the area translating matrix to origin
174
drawInLayer(GLO_EDGERELDATA, offsetFront);
175
GLHelper::setColor(RGBColor::BLACK);
176
// draw box lines
177
178
179
GLHelper::drawBoxLines(laneEdge->getLaneShape(), laneEdge->getShapeRotations(),
180
laneEdge->getShapeLengths(), laneWidth);
181
// translate to top
182
glTranslated(0, 0, 0.01);
183
GLHelper::setColor(color);
184
// draw internal box lines
185
GLHelper::drawBoxLines(laneEdge->getLaneShape(), laneEdge->getShapeRotations(),
186
laneEdge->getShapeLengths(), (laneWidth - 0.1));
187
// Pop last matrix
188
GLHelper::popMatrix();
189
// draw lock icon
190
GNEViewNetHelper::LockIcon::drawLockIcon(d, this, getType(), getPositionInView(), 1);
191
// draw filtered attribute
192
if (getParentEdges().front()->getChildLanes().front() == laneEdge) {
193
drawFilteredAttribute(s, laneEdge->getLaneShape(),
194
myNet->getViewNet()->getViewParent()->getEdgeRelDataFrame()->getAttributeSelector()->getFilteredAttribute(),
195
myNet->getViewNet()->getViewParent()->getEdgeRelDataFrame()->getIntervalSelector()->getDataInterval());
196
}
197
// draw dotted contour
198
segment->getContour()->drawDottedContours(s, d, this, s.dottedContourSettings.segmentWidth, true);
199
}
200
// draw dotted contour
201
if (getParentEdges().front() == segment->getLane()->getParentEdge()) {
202
segment->getContour()->calculateContourEdge(s, d, getParentEdges().front(), this, getType(), true, false);
203
}
204
if (getParentEdges().back() == segment->getLane()->getParentEdge()) {
205
segment->getContour()->calculateContourEdge(s, d, getParentEdges().back(), this, getType(), false, true);
206
}
207
// check if add this path element to redraw buffer
208
if (!gViewObjectsHandler.isPathElementMarkForRedraw(this) && segment->getContour()->checkDrawPathContour(s, d, this)) {
209
gViewObjectsHandler.addToRedrawPathElements(this);
210
}
211
212
}
213
}
214
215
216
void
217
GNEEdgeRelData::drawJunctionPartialGL(const GUIVisualizationSettings& s, const GNESegment* segment, const double /*offsetFront*/) const {
218
// get color
219
const auto color = setColor(s);
220
if ((color.alpha() != 0) && myNet->getViewNet()->getEditModes().isCurrentSupermodeData()) {
221
// get detail level
222
const auto d = s.getDetailLevel(1);
223
// get flag for only draw contour
224
225
// finish
226
227
// draw dotted contour
228
if (segment->getPreviousLane() && segment->getNextLane()) {
229
segment->getContour()->calculateContourEdges(s, d, segment->getPreviousLane()->getParentEdge(), segment->getNextLane()->getParentEdge());
230
}
231
// check if add this path element to redraw buffer
232
if (!gViewObjectsHandler.isPathElementMarkForRedraw(this) && segment->getContour()->checkDrawPathContour(s, d, this)) {
233
gViewObjectsHandler.addToRedrawPathElements(this);
234
}
235
}
236
}
237
238
239
GNELane*
240
GNEEdgeRelData::getFirstPathLane() const {
241
/* temporal */
242
return nullptr;
243
}
244
245
246
GNELane*
247
GNEEdgeRelData::getLastPathLane() const {
248
/* temporal */
249
return nullptr;
250
}
251
252
253
Position
254
GNEEdgeRelData::getPositionInView() const {
255
return getParentEdges().front()->getPositionInView();
256
}
257
258
259
void
260
GNEEdgeRelData::writeGenericData(OutputDevice& device) const {
261
// open device
262
device.openTag(SUMO_TAG_EDGEREL);
263
// write from
264
device.writeAttr(SUMO_ATTR_FROM, getParentEdges().front()->getID());
265
// write to
266
device.writeAttr(SUMO_ATTR_TO, getParentEdges().back()->getID());
267
// iterate over attributes
268
for (const auto& attribute : getParametersMap()) {
269
// write attribute (don't use writeParams)
270
device.writeAttr(attribute.first, attribute.second);
271
}
272
// close device
273
device.closeTag();
274
}
275
276
277
bool
278
GNEEdgeRelData::isGenericDataValid() const {
279
return true;
280
}
281
282
283
std::string
284
GNEEdgeRelData::getGenericDataProblem() const {
285
return "";
286
}
287
288
289
void
290
GNEEdgeRelData::fixGenericDataProblem() {
291
throw InvalidArgument(getTagStr() + " cannot fix any problem");
292
}
293
294
295
Boundary
296
GNEEdgeRelData::getCenteringBoundary() const {
297
return getParentEdges().front()->getCenteringBoundary();
298
}
299
300
301
std::string
302
GNEEdgeRelData::getAttribute(SumoXMLAttr key) const {
303
switch (key) {
304
case SUMO_ATTR_ID:
305
return getPartialID() + getParentEdges().front()->getID();
306
case SUMO_ATTR_FROM:
307
return getParentEdges().front()->getID();
308
case SUMO_ATTR_TO:
309
return getParentEdges().back()->getID();
310
case GNE_ATTR_DATASET:
311
return myDataIntervalParent->getDataSetParent()->getID();
312
case SUMO_ATTR_BEGIN:
313
return myDataIntervalParent->getAttribute(SUMO_ATTR_BEGIN);
314
case SUMO_ATTR_END:
315
return myDataIntervalParent->getAttribute(SUMO_ATTR_END);
316
default:
317
return getCommonAttribute(this, key);
318
}
319
}
320
321
322
double
323
GNEEdgeRelData::getAttributeDouble(SumoXMLAttr key) const {
324
throw InvalidArgument(getTagStr() + " doesn't have a double attribute of type '" + toString(key) + "'");
325
}
326
327
328
void
329
GNEEdgeRelData::setAttribute(SumoXMLAttr key, const std::string& value, GNEUndoList* undoList) {
330
if (value == getAttribute(key)) {
331
return; //avoid needless changes, later logic relies on the fact that attributes have changed
332
}
333
switch (key) {
334
case SUMO_ATTR_FROM:
335
case SUMO_ATTR_TO:
336
GNEChange_Attribute::changeAttribute(this, key, value, undoList);
337
break;
338
default:
339
setCommonAttribute(key, value, undoList);
340
break;
341
}
342
}
343
344
345
bool
346
GNEEdgeRelData::isValid(SumoXMLAttr key, const std::string& value) {
347
switch (key) {
348
case SUMO_ATTR_FROM:
349
return SUMOXMLDefinitions::isValidNetID(value) && (myNet->getAttributeCarriers()->retrieveEdge(value, false) != nullptr) &&
350
(value != getParentEdges().back()->getID());
351
case SUMO_ATTR_TO:
352
return SUMOXMLDefinitions::isValidNetID(value) && (myNet->getAttributeCarriers()->retrieveEdge(value, false) != nullptr) &&
353
(value != getParentEdges().front()->getID());
354
default:
355
return isCommonValid(key, value);
356
}
357
}
358
359
360
bool GNEEdgeRelData::isAttributeEnabled(SumoXMLAttr key) const {
361
switch (key) {
362
case SUMO_ATTR_ID:
363
return false;
364
default:
365
return true;
366
}
367
}
368
369
370
std::string
371
GNEEdgeRelData::getPopUpID() const {
372
return getTagStr();
373
}
374
375
376
std::string
377
GNEEdgeRelData::getHierarchyName() const {
378
return getTagStr() + ": " + getParentEdges().front()->getID() + "->" + getParentEdges().back()->getID();
379
}
380
381
382
void
383
GNEEdgeRelData::setAttribute(SumoXMLAttr key, const std::string& value) {
384
switch (key) {
385
case SUMO_ATTR_FROM: {
386
// change first edge
387
replaceFirstParentEdge(value);
388
break;
389
}
390
case SUMO_ATTR_TO: {
391
// change last edge
392
replaceLastParentEdge(value);
393
break;
394
}
395
default:
396
setCommonAttribute(this, key, value);
397
if (!isTemplate()) {
398
myDataIntervalParent->getDataSetParent()->updateAttributeColors();
399
}
400
break;
401
}
402
// mark interval toolbar for update
403
myNet->getViewNet()->getIntervalBar().markForUpdate();
404
}
405
406
/****************************************************************************/
407
408