Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
eclipse
GitHub Repository: eclipse/sumo
Path: blob/main/src/netedit/elements/data/GNEEdgeRelData.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 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->getViewParent()->getEdgeRelDataFrame()->getIntervalSelector()->getDataInterval();
68
const std::string filteredAttribute = myNet->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
default:
106
return 0;
107
}
108
}
109
110
111
bool
112
GNEEdgeRelData::isGenericDataVisible() const {
113
// obtain pointer to edge data frame (only for code legibly)
114
const GNEEdgeRelDataFrame* edgeRelDataFrame = myNet->getViewParent()->getEdgeRelDataFrame();
115
// get current data edit mode
116
DataEditMode dataMode = myNet->getViewNet()->getEditModes().dataEditMode;
117
// check if we have to filter generic data
118
if ((dataMode == DataEditMode::DATA_INSPECT) || (dataMode == DataEditMode::DATA_DELETE) || (dataMode == DataEditMode::DATA_SELECT)) {
119
return isVisibleInspectDeleteSelect();
120
} else if (edgeRelDataFrame->shown()) {
121
// check interval
122
if ((edgeRelDataFrame->getIntervalSelector()->getDataInterval() != nullptr) &&
123
(edgeRelDataFrame->getIntervalSelector()->getDataInterval() != myDataIntervalParent)) {
124
return false;
125
}
126
// check attribute
127
if ((edgeRelDataFrame->getAttributeSelector()->getFilteredAttribute().size() > 0) &&
128
(getParametersMap().count(edgeRelDataFrame->getAttributeSelector()->getFilteredAttribute()) == 0)) {
129
return false;
130
}
131
// all checks ok, then return true
132
return true;
133
} else {
134
// GNEEdgeRelDataFrame hidden, then return false
135
return false;
136
}
137
}
138
139
140
void
141
GNEEdgeRelData::updateGeometry() {
142
// just compute path
143
computePathElement();
144
}
145
146
147
void
148
GNEEdgeRelData::drawGL(const GUIVisualizationSettings& /*s*/) const {
149
// Nothing to draw
150
}
151
152
153
void
154
GNEEdgeRelData::computePathElement() {
155
// calculate path
156
myNet->getDataPathManager()->calculateConsecutivePathEdges(this, SVC_IGNORING, getParentEdges());
157
}
158
159
160
void
161
GNEEdgeRelData::drawLanePartialGL(const GUIVisualizationSettings& s, const GNESegment* segment, const double offsetFront) const {
162
// get color
163
const auto color = setColor(s);
164
if (segment->getLane() && (color.alpha() != 0) && myNet->getViewNet()->getEditModes().isCurrentSupermodeData()) {
165
// get detail level
166
const auto d = s.getDetailLevel(1);
167
// draw over all edge's lanes
168
for (const auto& laneEdge : segment->getLane()->getParentEdge()->getChildLanes()) {
169
// get lane width
170
const double laneWidth = s.addSize.getExaggeration(s, laneEdge) * s.edgeRelWidthExaggeration *
171
(laneEdge->getParentEdge()->getNBEdge()->getLaneWidth(laneEdge->getIndex()) * 0.5);
172
// Add a draw matrix
173
GLHelper::pushMatrix();
174
// Start with the drawing of the area translating matrix to origin
175
drawInLayer(GLO_EDGERELDATA, offsetFront);
176
GLHelper::setColor(RGBColor::BLACK);
177
// draw box lines
178
179
180
GLHelper::drawBoxLines(laneEdge->getLaneShape(), laneEdge->getShapeRotations(),
181
laneEdge->getShapeLengths(), laneWidth);
182
// translate to top
183
glTranslated(0, 0, 0.01);
184
GLHelper::setColor(color);
185
// draw internal box lines
186
GLHelper::drawBoxLines(laneEdge->getLaneShape(), laneEdge->getShapeRotations(),
187
laneEdge->getShapeLengths(), (laneWidth - 0.1));
188
// Pop last matrix
189
GLHelper::popMatrix();
190
// draw lock icon
191
GNEViewNetHelper::LockIcon::drawLockIcon(d, this, getType(), getPositionInView(), 1);
192
// draw filtered attribute
193
if (getParentEdges().front()->getChildLanes().front() == laneEdge) {
194
drawFilteredAttribute(s, laneEdge->getLaneShape(),
195
myNet->getViewParent()->getEdgeRelDataFrame()->getAttributeSelector()->getFilteredAttribute(),
196
myNet->getViewParent()->getEdgeRelDataFrame()->getIntervalSelector()->getDataInterval());
197
}
198
// draw dotted contour
199
segment->getContour()->drawDottedContours(s, d, this, s.dottedContourSettings.segmentWidth, true);
200
}
201
// draw dotted contour
202
if (getParentEdges().front() == segment->getLane()->getParentEdge()) {
203
segment->getContour()->calculateContourEdge(s, d, getParentEdges().front(), this, getType(), true, false);
204
}
205
if (getParentEdges().back() == segment->getLane()->getParentEdge()) {
206
segment->getContour()->calculateContourEdge(s, d, getParentEdges().back(), this, getType(), false, true);
207
}
208
// check if add this path element to redraw buffer
209
if (!gViewObjectsHandler.isPathElementMarkForRedraw(this) && segment->getContour()->checkDrawPathContour(s, d, this)) {
210
gViewObjectsHandler.addToRedrawPathElements(this);
211
}
212
213
}
214
}
215
216
217
void
218
GNEEdgeRelData::drawJunctionPartialGL(const GUIVisualizationSettings& s, const GNESegment* segment, const double /*offsetFront*/) const {
219
// get color
220
const auto color = setColor(s);
221
if ((color.alpha() != 0) && myNet->getViewNet()->getEditModes().isCurrentSupermodeData()) {
222
// get detail level
223
const auto d = s.getDetailLevel(1);
224
// get flag for only draw contour
225
226
// finish
227
228
// draw dotted contour
229
if (segment->getPreviousLane() && segment->getNextLane()) {
230
segment->getContour()->calculateContourEdges(s, d, segment->getPreviousLane()->getParentEdge(), segment->getNextLane()->getParentEdge());
231
}
232
// check if add this path element to redraw buffer
233
if (!gViewObjectsHandler.isPathElementMarkForRedraw(this) && segment->getContour()->checkDrawPathContour(s, d, this)) {
234
gViewObjectsHandler.addToRedrawPathElements(this);
235
}
236
}
237
}
238
239
240
GNELane*
241
GNEEdgeRelData::getFirstPathLane() const {
242
/* temporal */
243
return nullptr;
244
}
245
246
247
GNELane*
248
GNEEdgeRelData::getLastPathLane() const {
249
/* temporal */
250
return nullptr;
251
}
252
253
254
Position
255
GNEEdgeRelData::getPositionInView() const {
256
return getParentEdges().front()->getPositionInView();
257
}
258
259
260
void
261
GNEEdgeRelData::writeGenericData(OutputDevice& device) const {
262
// open device
263
device.openTag(SUMO_TAG_EDGEREL);
264
// write from
265
device.writeAttr(SUMO_ATTR_FROM, getParentEdges().front()->getID());
266
// write to
267
device.writeAttr(SUMO_ATTR_TO, getParentEdges().back()->getID());
268
// iterate over attributes
269
for (const auto& attribute : getParametersMap()) {
270
// write attribute (don't use writeParams)
271
device.writeAttr(attribute.first, attribute.second);
272
}
273
// close device
274
device.closeTag();
275
}
276
277
278
bool
279
GNEEdgeRelData::isGenericDataValid() const {
280
return true;
281
}
282
283
284
std::string
285
GNEEdgeRelData::getGenericDataProblem() const {
286
return "";
287
}
288
289
290
void
291
GNEEdgeRelData::fixGenericDataProblem() {
292
throw InvalidArgument(getTagStr() + " cannot fix any problem");
293
}
294
295
296
Boundary
297
GNEEdgeRelData::getCenteringBoundary() const {
298
return getParentEdges().front()->getCenteringBoundary();
299
}
300
301
302
std::string
303
GNEEdgeRelData::getAttribute(SumoXMLAttr key) const {
304
switch (key) {
305
case SUMO_ATTR_ID:
306
return getPartialID() + getParentEdges().front()->getID();
307
case SUMO_ATTR_FROM:
308
return getParentEdges().front()->getID();
309
case SUMO_ATTR_TO:
310
return getParentEdges().back()->getID();
311
case GNE_ATTR_DATASET:
312
return myDataIntervalParent->getDataSetParent()->getID();
313
case SUMO_ATTR_BEGIN:
314
return myDataIntervalParent->getAttribute(SUMO_ATTR_BEGIN);
315
case SUMO_ATTR_END:
316
return myDataIntervalParent->getAttribute(SUMO_ATTR_END);
317
default:
318
return getCommonAttribute(key);
319
}
320
}
321
322
323
double
324
GNEEdgeRelData::getAttributeDouble(SumoXMLAttr key) const {
325
return getCommonAttributeDouble(key);
326
}
327
328
329
void
330
GNEEdgeRelData::setAttribute(SumoXMLAttr key, const std::string& value, GNEUndoList* undoList) {
331
if (value == getAttribute(key)) {
332
return; //avoid needless changes, later logic relies on the fact that attributes have changed
333
}
334
switch (key) {
335
case SUMO_ATTR_FROM:
336
case SUMO_ATTR_TO:
337
GNEChange_Attribute::changeAttribute(this, key, value, undoList);
338
break;
339
default:
340
setCommonAttribute(key, value, undoList);
341
break;
342
}
343
}
344
345
346
bool
347
GNEEdgeRelData::isValid(SumoXMLAttr key, const std::string& value) {
348
switch (key) {
349
case SUMO_ATTR_FROM:
350
return SUMOXMLDefinitions::isValidNetID(value) && (myNet->getAttributeCarriers()->retrieveEdge(value, false) != nullptr) &&
351
(value != getParentEdges().back()->getID());
352
case SUMO_ATTR_TO:
353
return SUMOXMLDefinitions::isValidNetID(value) && (myNet->getAttributeCarriers()->retrieveEdge(value, false) != nullptr) &&
354
(value != getParentEdges().front()->getID());
355
default:
356
return isCommonAttributeValid(key, value);
357
}
358
}
359
360
361
bool GNEEdgeRelData::isAttributeEnabled(SumoXMLAttr key) const {
362
switch (key) {
363
case SUMO_ATTR_ID:
364
return false;
365
default:
366
return true;
367
}
368
}
369
370
371
std::string
372
GNEEdgeRelData::getPopUpID() const {
373
return getTagStr();
374
}
375
376
377
std::string
378
GNEEdgeRelData::getHierarchyName() const {
379
return getTagStr() + ": " + getParentEdges().front()->getID() + "->" + getParentEdges().back()->getID();
380
}
381
382
383
void
384
GNEEdgeRelData::setAttribute(SumoXMLAttr key, const std::string& value) {
385
switch (key) {
386
case SUMO_ATTR_FROM: {
387
// change first edge
388
replaceFirstParentEdge(value);
389
break;
390
}
391
case SUMO_ATTR_TO: {
392
// change last edge
393
replaceLastParentEdge(value);
394
break;
395
}
396
default:
397
setCommonAttribute(key, value);
398
if (!isTemplate()) {
399
myDataIntervalParent->getDataSetParent()->updateAttributeColors();
400
}
401
break;
402
}
403
// mark interval toolbar for update
404
if (!isTemplate()) {
405
myNet->getViewNet()->getIntervalBar().markForUpdate();
406
}
407
}
408
409
/****************************************************************************/
410
411