Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
eclipse
GitHub Repository: eclipse/sumo
Path: blob/main/src/netedit/elements/data/GNETAZRelData.cpp
169685 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 GNETAZRelData.cpp
15
/// @author Pablo Alvarez Lopez
16
/// @date Jan 2020
17
///
18
// class for TAZ relation data
19
/****************************************************************************/
20
21
#include <netedit/GNENet.h>
22
#include <netedit/GNETagProperties.h>
23
#include <netedit/GNEUndoList.h>
24
#include <netedit/GNEViewNet.h>
25
#include <netedit/GNEViewParent.h>
26
#include <netedit/changes/GNEChange_Attribute.h>
27
#include <netedit/elements/additional/GNETAZ.h>
28
#include <netedit/frames/data/GNETAZRelDataFrame.h>
29
#include <utils/gui/div/GLHelper.h>
30
#include <utils/gui/div/GUIGlobalViewObjectsHandler.h>
31
#include <utils/gui/globjects/GLIncludes.h>
32
33
#include "GNETAZRelData.h"
34
#include "GNEDataInterval.h"
35
36
// ===========================================================================
37
// member method definitions
38
// ===========================================================================
39
40
GNETAZRelData::GNETAZRelData(GNENet* net) :
41
GNEGenericData(SUMO_TAG_TAZREL, net),
42
myLastWidth(0) {
43
}
44
45
46
GNETAZRelData::GNETAZRelData(GNEDataInterval* dataIntervalParent, GNEAdditional* fromTAZ, GNEAdditional* toTAZ,
47
const Parameterised::Map& parameters) :
48
GNEGenericData(SUMO_TAG_TAZREL, dataIntervalParent, parameters),
49
myLastWidth(0) {
50
// set parents
51
setParents<GNEAdditional*>({fromTAZ, toTAZ});
52
}
53
54
55
GNETAZRelData::GNETAZRelData(GNEDataInterval* dataIntervalParent, GNEAdditional* TAZ,
56
const Parameterised::Map& parameters) :
57
GNEGenericData(SUMO_TAG_TAZREL, dataIntervalParent, parameters),
58
myLastWidth(0) {
59
// set parents
60
setParent<GNEAdditional*>(TAZ);
61
}
62
63
64
GNETAZRelData::~GNETAZRelData() {}
65
66
67
RGBColor
68
GNETAZRelData::setColor(const GUIVisualizationSettings& s) const {
69
RGBColor color;
70
if (isAttributeCarrierSelected()) {
71
color = s.colorSettings.selectedEdgeDataColor;
72
} else {
73
if (!setFunctionalColor(s.dataColorer.getActive(), color)) {
74
double val = getColorValue(s, s.dataColorer.getActive());
75
color = s.dataColorer.getScheme().getColor(val);
76
}
77
}
78
return color;
79
}
80
81
82
double
83
GNETAZRelData::getColorValue(const GUIVisualizationSettings& s, int activeScheme) const {
84
switch (activeScheme) {
85
case 0:
86
return 0;
87
case 1:
88
return isAttributeCarrierSelected();
89
case 2:
90
return 0; // setfunctional color const GNEAdditional* TAZA = getParentAdditionals().front();
91
case 3:
92
return 0; // setfunctional color const GNEAdditional* TAZA = getParentAdditionals().back();
93
case 4:
94
// by numerical attribute value
95
try {
96
if (hasParameter(s.relDataAttr)) {
97
return StringUtils::toDouble(getParameter(s.relDataAttr, "-1"));
98
} else {
99
return GUIVisualizationSettings::MISSING_DATA;
100
}
101
} catch (NumberFormatException&) {
102
return GUIVisualizationSettings::MISSING_DATA;
103
}
104
105
}
106
return 0;
107
108
}
109
110
111
bool
112
GNETAZRelData::isGenericDataVisible() const {
113
// obtain pointer to TAZ data frame (only for code legibly)
114
const GNETAZRelDataFrame* TAZRelDataFrame = myNet->getViewNet()->getViewParent()->getTAZRelDataFrame();
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()*/ true;
120
} else if (TAZRelDataFrame->shown()) {
121
// check interval
122
if ((TAZRelDataFrame->getIntervalSelector()->getDataInterval() != nullptr) &&
123
(TAZRelDataFrame->getIntervalSelector()->getDataInterval() != myDataIntervalParent)) {
124
return false;
125
}
126
// check attribute
127
if ((TAZRelDataFrame->getAttributeSelector()->getFilteredAttribute().size() > 0) &&
128
(getParametersMap().count(TAZRelDataFrame->getAttributeSelector()->getFilteredAttribute()) == 0)) {
129
return false;
130
}
131
// all checks ok, then return true
132
return true;
133
} else {
134
// GNETAZRelDataFrame hidden, then return false
135
return false;
136
}
137
}
138
139
140
void
141
GNETAZRelData::updateGeometry() {
142
// remove from grid
143
myNet->removeGLObjectFromGrid(this);
144
// get both TAZs
145
const GNEAdditional* TAZA = getParentAdditionals().front();
146
const GNEAdditional* TAZB = getParentAdditionals().back();
147
// check if this is the same TAZ
148
if (TAZA == TAZB) {
149
// declare ring
150
PositionVector ring;
151
// declare first point
152
std::pair<double, double> p1 = GLHelper::getCircleCoords().at(GLHelper::angleLookup(0));
153
// add 8 segments
154
for (int i = 0; i <= 8; ++i) {
155
const std::pair<double, double>& p2 = GLHelper::getCircleCoords().at(GLHelper::angleLookup(0 + i * 45));
156
// make al line between 0,0 and p2
157
PositionVector line = {Position(), Position(p2.first, p2.second)};
158
// extrapolate
159
line.extrapolate(3, false, true);
160
// add line back to ring
161
ring.push_back(line.back());
162
// update p1
163
p1 = p2;
164
}
165
// make a copy of ring
166
PositionVector ringCenter = ring;
167
// move ring to first geometry point
168
ring.add(TAZA->getAdditionalGeometry().getShape().front());
169
myTAZRelGeometry.updateGeometry(ring);
170
// move ringCenter to center
171
ringCenter.add(TAZA->getAttributePosition(SUMO_ATTR_CENTER));
172
myTAZRelGeometryCenter.updateGeometry(ringCenter);
173
} else {
174
// calculate line between to TAZ centers
175
PositionVector line = {TAZA->getAttributePosition(SUMO_ATTR_CENTER), TAZB->getAttributePosition(SUMO_ATTR_CENTER)};
176
// check line
177
if (line.length() < 1) {
178
line = {TAZA->getAttributePosition(SUMO_ATTR_CENTER) - 0.5, TAZB->getAttributePosition(SUMO_ATTR_CENTER) + 0.5};
179
}
180
// add offset to line
181
line.move2side(0.5 + myLastWidth);
182
// calculate middle point
183
const Position middlePoint = line.getLineCenter();
184
// get closest points to middlePoint
185
Position posA = TAZA->getAdditionalGeometry().getShape().positionAtOffset2D(TAZA->getAdditionalGeometry().getShape().nearest_offset_to_point2D(middlePoint));
186
Position posB = TAZB->getAdditionalGeometry().getShape().positionAtOffset2D(TAZB->getAdditionalGeometry().getShape().nearest_offset_to_point2D(middlePoint));
187
// check positions
188
if (posA == Position::INVALID) {
189
posA = TAZA->getAdditionalGeometry().getShape().front();
190
}
191
if (posB == Position::INVALID) {
192
posB = TAZB->getAdditionalGeometry().getShape().front();
193
}
194
// update geometry
195
if (posA.distanceTo(posB) < 1) {
196
myTAZRelGeometry.updateGeometry({posA - 0.5, posB + 0.5});
197
} else {
198
myTAZRelGeometry.updateGeometry({posA, posB});
199
}
200
// update center geometry
201
myTAZRelGeometryCenter.updateGeometry(line);
202
}
203
// add into grid again
204
myNet->addGLObjectIntoGrid(this);
205
}
206
207
208
Position
209
GNETAZRelData::getPositionInView() const {
210
return getParentAdditionals().front()->getAttributePosition(SUMO_ATTR_CENTER);
211
}
212
213
214
void
215
GNETAZRelData::writeGenericData(OutputDevice& device) const {
216
// open device
217
device.openTag(SUMO_TAG_TAZREL);
218
// write from
219
device.writeAttr(SUMO_ATTR_FROM, getParentAdditionals().front()->getID());
220
// write to
221
device.writeAttr(SUMO_ATTR_TO, getParentAdditionals().back()->getID());
222
// iterate over attributes
223
for (const auto& attribute : getParametersMap()) {
224
// write attribute (don't use writeParams)
225
device.writeAttr(attribute.first, attribute.second);
226
}
227
// close device
228
device.closeTag();
229
}
230
231
232
bool
233
GNETAZRelData::isGenericDataValid() const {
234
return true;
235
}
236
237
238
std::string
239
GNETAZRelData::getGenericDataProblem() const {
240
return "";
241
}
242
243
244
void
245
GNETAZRelData::fixGenericDataProblem() {
246
throw InvalidArgument(getTagStr() + " cannot fix any problem");
247
}
248
249
250
void
251
GNETAZRelData::drawGL(const GUIVisualizationSettings& s) const {
252
// draw boundaries
253
GLHelper::drawBoundary(s, getCenteringBoundary());
254
// draw TAZRels
255
if (drawTAZRel()) {
256
// get detail level
257
const auto d = s.getDetailLevel(1);
258
// draw geometry only if we'rent in drawForObjectUnderCursor mode
259
if (!s.drawForViewObjectsHandler) {
260
const auto& color = setColor(s);
261
// get flag for only draw contour
262
const bool onlyDrawContour = !isGenericDataVisible();
263
// push matrix
264
GLHelper::pushMatrix();
265
// translate to front
266
drawInLayer(GLO_TAZ + 1);
267
GLHelper::setColor(color);
268
// check if update lastWidth
269
const double width = onlyDrawContour ? 0.1 : 0.5 * s.tazRelWidthExaggeration;
270
if (width != myLastWidth) {
271
myLastWidth = width;
272
}
273
// draw geometry
274
if (onlyDrawContour) {
275
// draw depending of TAZRelDrawing
276
if (myNet->getViewNet()->getDataViewOptions().TAZRelDrawing()) {
277
GUIGeometry::drawGeometry(d, myTAZRelGeometryCenter, width);
278
} else {
279
GUIGeometry::drawGeometry(d, myTAZRelGeometry, width);
280
}
281
} else {
282
// draw depending of TAZRelDrawing
283
const GUIGeometry& geom = (myNet->getViewNet()->getDataViewOptions().TAZRelDrawing()
284
? myTAZRelGeometryCenter : myTAZRelGeometry);
285
GUIGeometry::drawGeometry(d, geom, width);
286
GLHelper::drawTriangleAtEnd(
287
*(geom.getShape().end() - 2),
288
*(geom.getShape().end() - 1),
289
1.5 + width, 1.5 + width, 0.5 + width);
290
}
291
// pop matrix
292
GLHelper::popMatrix();
293
// draw dotted contour
294
myTAZRelDataContour.drawDottedContours(s, d, this, s.dottedContourSettings.segmentWidth, true);
295
}
296
if (myNet->getViewNet()->getDataViewOptions().TAZRelDrawing()) {
297
// calculate contour and draw dotted geometry
298
myTAZRelDataContour.calculateContourExtrudedShape(s, d, this, myTAZRelGeometryCenter.getShape(), getType(),
299
0.5, 1, true, true, 0, nullptr, nullptr);
300
} else {
301
// calculate contour and draw dotted geometry
302
myTAZRelDataContour.calculateContourExtrudedShape(s, d, this, myTAZRelGeometry.getShape(), getType(),
303
0.5, 1, true, true, 0, nullptr, nullptr);
304
}
305
}
306
}
307
308
309
bool
310
GNETAZRelData::setFunctionalColor(int activeScheme, RGBColor& col) const {
311
switch (activeScheme) {
312
case 2: { // origin taz
313
const GNETAZ* from = dynamic_cast<const GNETAZ*>(getParentAdditionals().front());
314
col = from->getShapeColor();
315
return true;
316
}
317
case 3: { // destination taz
318
const GNETAZ* to = dynamic_cast<const GNETAZ*>(getParentAdditionals().back());
319
col = to->getShapeColor();
320
return true;
321
}
322
default:
323
return false;
324
}
325
}
326
327
void
328
GNETAZRelData::computePathElement() {
329
// nothing to compute
330
}
331
332
333
void
334
GNETAZRelData::drawLanePartialGL(const GUIVisualizationSettings& /*s*/, const GNESegment* /*segment*/, const double /*offsetFront*/) const {
335
// nothing to draw
336
}
337
338
339
void
340
GNETAZRelData::drawJunctionPartialGL(const GUIVisualizationSettings& /*s*/, const GNESegment* /*segment*/, const double /*offsetFront*/) const {
341
// nothing to draw
342
}
343
344
345
GNELane*
346
GNETAZRelData::getFirstPathLane() const {
347
return nullptr;
348
}
349
350
351
GNELane*
352
GNETAZRelData::getLastPathLane() const {
353
return nullptr;
354
}
355
356
357
Boundary
358
GNETAZRelData::getCenteringBoundary() const {
359
Boundary b;
360
// add two shapes
361
b.add(myTAZRelGeometry.getShape().getBoxBoundary());
362
b.add(myTAZRelGeometryCenter.getShape().getBoxBoundary());
363
b.grow(20);
364
return b;
365
}
366
367
368
std::string
369
GNETAZRelData::getAttribute(SumoXMLAttr key) const {
370
switch (key) {
371
case SUMO_ATTR_ID:
372
if (getParentAdditionals().size() == 1) {
373
return getPartialID() + getParentAdditionals().front()->getID();
374
} else {
375
return getPartialID() + (getParentAdditionals().front()->getID() + "->" + getParentAdditionals().back()->getID());
376
}
377
case SUMO_ATTR_FROM:
378
return getParentAdditionals().front()->getID();
379
case SUMO_ATTR_TO:
380
return getParentAdditionals().back()->getID();
381
case GNE_ATTR_DATASET:
382
return myDataIntervalParent->getDataSetParent()->getID();
383
case SUMO_ATTR_BEGIN:
384
return myDataIntervalParent->getAttribute(SUMO_ATTR_BEGIN);
385
case SUMO_ATTR_END:
386
return myDataIntervalParent->getAttribute(SUMO_ATTR_END);
387
default:
388
return getCommonAttribute(this, key);
389
}
390
}
391
392
393
double
394
GNETAZRelData::getAttributeDouble(SumoXMLAttr key) const {
395
throw InvalidArgument(getTagStr() + " doesn't have a double attribute of type '" + toString(key) + "'");
396
}
397
398
399
void
400
GNETAZRelData::setAttribute(SumoXMLAttr key, const std::string& value, GNEUndoList* undoList) {
401
if (value == getAttribute(key)) {
402
return; //avoid needless changes, later logic relies on the fact that attributes have changed
403
}
404
switch (key) {
405
case SUMO_ATTR_FROM:
406
case SUMO_ATTR_TO:
407
GNEChange_Attribute::changeAttribute(this, key, value, undoList);
408
break;
409
default:
410
setCommonAttribute(key, value, undoList);
411
break;
412
}
413
}
414
415
416
bool
417
GNETAZRelData::isValid(SumoXMLAttr key, const std::string& value) {
418
switch (key) {
419
case SUMO_ATTR_FROM:
420
case SUMO_ATTR_TO:
421
return SUMOXMLDefinitions::isValidNetID(value) &&
422
(myNet->getAttributeCarriers()->retrieveAdditional(SUMO_TAG_TAZ, value, false) != nullptr);
423
default:
424
return isCommonValid(key, value);
425
}
426
}
427
428
429
bool GNETAZRelData::isAttributeEnabled(SumoXMLAttr key) const {
430
switch (key) {
431
case SUMO_ATTR_ID:
432
return false;
433
default:
434
return true;
435
}
436
}
437
438
439
std::string
440
GNETAZRelData::getPopUpID() const {
441
return getTagStr();
442
}
443
444
445
std::string
446
GNETAZRelData::getHierarchyName() const {
447
if (getParentAdditionals().size() == 1) {
448
return getTagStr() + ": " + getParentAdditionals().front()->getID();
449
} else {
450
return getTagStr() + ": " + getParentAdditionals().front()->getID() + "->" + getParentAdditionals().back()->getID();
451
}
452
}
453
454
455
bool
456
GNETAZRelData::drawTAZRel() const {
457
const auto& inspectedElements = myNet->getViewNet()->getInspectedElements();
458
// first check supermode
459
if (!myNet->getViewNet()->getEditModes().isCurrentSupermodeData()) {
460
return false;
461
}
462
// check TAZRelFrame
463
if (myNet->getViewNet()->getViewParent()->getTAZRelDataFrame()->shown()) {
464
// check dataSet
465
const GNEDataSet* dataSet = myNet->getViewNet()->getViewParent()->getTAZRelDataFrame()->getDataSetSelector()->getDataSet();
466
if (dataSet && (myDataIntervalParent->getDataSetParent() != dataSet)) {
467
return false;
468
}
469
// check interval
470
const GNEDataInterval* dataInterval = myNet->getViewNet()->getViewParent()->getTAZRelDataFrame()->getIntervalSelector()->getDataInterval();
471
if (dataInterval && (myDataIntervalParent != dataInterval)) {
472
return false;
473
}
474
}
475
// check if both draw TAZRel checkBox are disabled
476
if (!myNet->getViewNet()->getDataViewOptions().TAZRelOnlyFrom() && !myNet->getViewNet()->getDataViewOptions().TAZRelOnlyTo()) {
477
return false;
478
}
479
// check if we're inspecting a TAZ
480
if ((myNet->getViewNet()->getEditModes().dataEditMode == DataEditMode::DATA_INSPECT) &&
481
inspectedElements.isInspectingSingleElement() && (inspectedElements.getFirstAC()->getTagProperty()->getTag() == SUMO_TAG_TAZ)) {
482
// ignore TAZRels with one TAZParent
483
if (getParentAdditionals().size() == 2) {
484
if ((getParentAdditionals().front() == inspectedElements.getFirstAC()) &&
485
myNet->getViewNet()->getDataViewOptions().TAZRelOnlyFrom()) {
486
return true;
487
} else if ((getParentAdditionals().back() == inspectedElements.getFirstAC()) &&
488
myNet->getViewNet()->getDataViewOptions().TAZRelOnlyTo()) {
489
return true;
490
} else {
491
return false;
492
}
493
}
494
}
495
return true;
496
}
497
498
499
void
500
GNETAZRelData::setAttribute(SumoXMLAttr key, const std::string& value) {
501
switch (key) {
502
case SUMO_ATTR_FROM: {
503
// replace first TAZ Parent
504
replaceParentTAZElement(0, value);
505
// update geometry
506
updateGeometry();
507
break;
508
}
509
case SUMO_ATTR_TO: {
510
// replace second TAZ Parent
511
replaceParentTAZElement(1, value);
512
// update geometry
513
updateGeometry();
514
break;
515
}
516
default:
517
setCommonAttribute(this, key, value);
518
if (!isTemplate()) {
519
myDataIntervalParent->getDataSetParent()->updateAttributeColors();
520
}
521
break;
522
}
523
// mark interval toolbar for update
524
myNet->getViewNet()->getIntervalBar().markForUpdate();
525
}
526
527
/****************************************************************************/
528
529