Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
eclipse
GitHub Repository: eclipse/sumo
Path: blob/main/src/netedit/elements/data/GNETAZRelData.cpp
193692 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 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
default:
105
return 0;
106
}
107
}
108
109
110
double
111
GNETAZRelData::getScaleValue(const GUIVisualizationSettings& s, int activeScheme) const {
112
switch (activeScheme) {
113
case 0: // uniform
114
return 0;
115
case 1: // selection
116
return isAttributeCarrierSelected();
117
case 2: // by numerical attribute value
118
try {
119
if (hasParameter(s.relDataScaleAttr)) {
120
return StringUtils::toDouble(getParameter(s.relDataScaleAttr, "-1"));
121
} else {
122
return GUIVisualizationSettings::MISSING_DATA;
123
}
124
} catch (NumberFormatException&) {
125
return GUIVisualizationSettings::MISSING_DATA;
126
}
127
default:
128
return 0;
129
}
130
}
131
132
133
134
bool
135
GNETAZRelData::isGenericDataVisible() const {
136
// obtain pointer to TAZ data frame (only for code legibly)
137
const GNETAZRelDataFrame* TAZRelDataFrame = myNet->getViewParent()->getTAZRelDataFrame();
138
// get current data edit mode
139
DataEditMode dataMode = myNet->getViewNet()->getEditModes().dataEditMode;
140
// check if we have to filter generic data
141
if ((dataMode == DataEditMode::DATA_INSPECT) || (dataMode == DataEditMode::DATA_DELETE) || (dataMode == DataEditMode::DATA_SELECT)) {
142
return /*isVisibleInspectDeleteSelect()*/ true;
143
} else if (TAZRelDataFrame->shown()) {
144
// check interval
145
if ((TAZRelDataFrame->getIntervalSelector()->getDataInterval() != nullptr) &&
146
(TAZRelDataFrame->getIntervalSelector()->getDataInterval() != myDataIntervalParent)) {
147
return false;
148
}
149
// check attribute
150
if ((TAZRelDataFrame->getAttributeSelector()->getFilteredAttribute().size() > 0) &&
151
(getParametersMap().count(TAZRelDataFrame->getAttributeSelector()->getFilteredAttribute()) == 0)) {
152
return false;
153
}
154
// all checks ok, then return true
155
return true;
156
} else {
157
// GNETAZRelDataFrame hidden, then return false
158
return false;
159
}
160
}
161
162
163
void
164
GNETAZRelData::updateGeometry() {
165
// remove from grid
166
myNet->removeGLObjectFromGrid(this);
167
// get both TAZs
168
const GNEAdditional* TAZA = getParentAdditionals().front();
169
const GNEAdditional* TAZB = getParentAdditionals().back();
170
// check if this is the same TAZ
171
if (TAZA == TAZB) {
172
// declare ring
173
PositionVector ring;
174
// declare first point
175
std::pair<double, double> p1 = GLHelper::getCircleCoords().at(GLHelper::angleLookup(0));
176
// add 8 segments
177
for (int i = 0; i <= 8; ++i) {
178
const std::pair<double, double>& p2 = GLHelper::getCircleCoords().at(GLHelper::angleLookup(0 + i * 45));
179
// make al line between 0,0 and p2
180
PositionVector line = {Position(), Position(p2.first, p2.second)};
181
// extrapolate
182
line.extrapolate(3, false, true);
183
// add line back to ring
184
ring.push_back(line.back());
185
// update p1
186
p1 = p2;
187
}
188
// make a copy of ring
189
PositionVector ringCenter = ring;
190
// move ring to first geometry point
191
ring.add(TAZA->getAdditionalGeometry().getShape().front());
192
myTAZRelGeometry.updateGeometry(ring);
193
// move ringCenter to center
194
ringCenter.add(TAZA->getAttributePosition(SUMO_ATTR_CENTER));
195
myTAZRelGeometryCenter.updateGeometry(ringCenter);
196
} else {
197
// calculate line between to TAZ centers
198
PositionVector line = {TAZA->getAttributePosition(SUMO_ATTR_CENTER), TAZB->getAttributePosition(SUMO_ATTR_CENTER)};
199
// check line
200
if (line.length() < 1) {
201
line = {TAZA->getAttributePosition(SUMO_ATTR_CENTER) - 0.5, TAZB->getAttributePosition(SUMO_ATTR_CENTER) + 0.5};
202
}
203
// add offset to line
204
line.move2side(0.5 + myLastWidth);
205
// calculate middle point
206
const Position middlePoint = line.getLineCenter();
207
// get closest points to middlePoint
208
Position posA = TAZA->getAdditionalGeometry().getShape().positionAtOffset2D(TAZA->getAdditionalGeometry().getShape().nearest_offset_to_point2D(middlePoint));
209
Position posB = TAZB->getAdditionalGeometry().getShape().positionAtOffset2D(TAZB->getAdditionalGeometry().getShape().nearest_offset_to_point2D(middlePoint));
210
// check positions
211
if (posA == Position::INVALID) {
212
posA = TAZA->getAdditionalGeometry().getShape().front();
213
}
214
if (posB == Position::INVALID) {
215
posB = TAZB->getAdditionalGeometry().getShape().front();
216
}
217
// update geometry
218
if (posA.distanceTo(posB) < 1) {
219
myTAZRelGeometry.updateGeometry({posA - 0.5, posB + 0.5});
220
} else {
221
myTAZRelGeometry.updateGeometry({posA, posB});
222
}
223
// update center geometry
224
myTAZRelGeometryCenter.updateGeometry(line);
225
}
226
// add into grid again
227
myNet->addGLObjectIntoGrid(this);
228
}
229
230
231
Position
232
GNETAZRelData::getPositionInView() const {
233
return getParentAdditionals().front()->getAttributePosition(SUMO_ATTR_CENTER);
234
}
235
236
237
void
238
GNETAZRelData::writeGenericData(OutputDevice& device) const {
239
// open device
240
device.openTag(SUMO_TAG_TAZREL);
241
// write from
242
device.writeAttr(SUMO_ATTR_FROM, getParentAdditionals().front()->getID());
243
// write to
244
device.writeAttr(SUMO_ATTR_TO, getParentAdditionals().back()->getID());
245
// iterate over attributes
246
for (const auto& attribute : getParametersMap()) {
247
// write attribute (don't use writeParams)
248
device.writeAttr(attribute.first, attribute.second);
249
}
250
// close device
251
device.closeTag();
252
}
253
254
255
bool
256
GNETAZRelData::isGenericDataValid() const {
257
return true;
258
}
259
260
261
std::string
262
GNETAZRelData::getGenericDataProblem() const {
263
return "";
264
}
265
266
267
void
268
GNETAZRelData::fixGenericDataProblem() {
269
throw InvalidArgument(getTagStr() + " cannot fix any problem");
270
}
271
272
273
void
274
GNETAZRelData::drawGL(const GUIVisualizationSettings& s) const {
275
// draw boundaries
276
GLHelper::drawBoundary(s, getCenteringBoundary());
277
// draw TAZRels
278
if (drawTAZRel()) {
279
// fixed detail level because tazRelations need high detail when zoomed out
280
const auto d = GUIVisualizationSettings::Detail::Level1;
281
// draw geometry only if we'rent in drawForObjectUnderCursor mode
282
if (!s.drawForViewObjectsHandler) {
283
const auto& color = setColor(s);
284
// get flag for only draw contour
285
const bool onlyDrawContour = !isGenericDataVisible();
286
// push matrix
287
GLHelper::pushMatrix();
288
// translate to front
289
drawInLayer(GLO_TAZ + 1);
290
GLHelper::setColor(color);
291
// check if update lastWidth
292
const double selectionScale = isAttributeCarrierSelected() ? s.selectorFrameScale : 1;
293
const double width = (onlyDrawContour ? 0.1 : 0.5 * s.tazRelWidthExaggeration * selectionScale
294
* s.dataScaler.getScheme().getColor(getScaleValue(s, s.dataScaler.getActive())));
295
if (width != myLastWidth) {
296
myLastWidth = width;
297
}
298
// draw geometry
299
if (onlyDrawContour) {
300
// draw depending of TAZRelDrawing
301
if (myNet->getViewNet()->getDataViewOptions().TAZRelDrawing()) {
302
GUIGeometry::drawGeometry(d, myTAZRelGeometryCenter, width);
303
} else {
304
GUIGeometry::drawGeometry(d, myTAZRelGeometry, width);
305
}
306
} else {
307
// draw depending of TAZRelDrawing
308
const GUIGeometry& geom = (myNet->getViewNet()->getDataViewOptions().TAZRelDrawing()
309
? myTAZRelGeometryCenter : myTAZRelGeometry);
310
GUIGeometry::drawGeometry(d, geom, width);
311
GLHelper::drawTriangleAtEnd(
312
*(geom.getShape().end() - 2),
313
*(geom.getShape().end() - 1),
314
1.5 + width, 1.5 + width, 0.5 + width);
315
}
316
// pop matrix
317
GLHelper::popMatrix();
318
// draw dotted contour
319
myTAZRelDataContour.drawDottedContours(s, d, this, s.dottedContourSettings.segmentWidth, true);
320
}
321
if (myNet->getViewNet()->getDataViewOptions().TAZRelDrawing()) {
322
// calculate contour and draw dotted geometry
323
myTAZRelDataContour.calculateContourExtrudedShape(s, d, this, myTAZRelGeometryCenter.getShape(), getType(),
324
0.5, 1, true, true, 0, nullptr, nullptr);
325
} else {
326
// calculate contour and draw dotted geometry
327
myTAZRelDataContour.calculateContourExtrudedShape(s, d, this, myTAZRelGeometry.getShape(), getType(),
328
0.5, 1, true, true, 0, nullptr, nullptr);
329
}
330
}
331
}
332
333
334
bool
335
GNETAZRelData::setFunctionalColor(int activeScheme, RGBColor& col) const {
336
switch (activeScheme) {
337
case 2: { // origin taz
338
const GNETAZ* from = dynamic_cast<const GNETAZ*>(getParentAdditionals().front());
339
col = from->getShapeColor();
340
return true;
341
}
342
case 3: { // destination taz
343
const GNETAZ* to = dynamic_cast<const GNETAZ*>(getParentAdditionals().back());
344
col = to->getShapeColor();
345
return true;
346
}
347
default:
348
return false;
349
}
350
}
351
352
void
353
GNETAZRelData::computePathElement() {
354
// nothing to compute
355
}
356
357
358
void
359
GNETAZRelData::drawLanePartialGL(const GUIVisualizationSettings& /*s*/, const GNESegment* /*segment*/, const double /*offsetFront*/) const {
360
// nothing to draw
361
}
362
363
364
void
365
GNETAZRelData::drawJunctionPartialGL(const GUIVisualizationSettings& /*s*/, const GNESegment* /*segment*/, const double /*offsetFront*/) const {
366
// nothing to draw
367
}
368
369
370
GNELane*
371
GNETAZRelData::getFirstPathLane() const {
372
return nullptr;
373
}
374
375
376
GNELane*
377
GNETAZRelData::getLastPathLane() const {
378
return nullptr;
379
}
380
381
382
Boundary
383
GNETAZRelData::getCenteringBoundary() const {
384
Boundary b;
385
// add two shapes
386
b.add(myTAZRelGeometry.getShape().getBoxBoundary());
387
b.add(myTAZRelGeometryCenter.getShape().getBoxBoundary());
388
b.grow(20);
389
return b;
390
}
391
392
393
std::string
394
GNETAZRelData::getAttribute(SumoXMLAttr key) const {
395
switch (key) {
396
case SUMO_ATTR_ID:
397
if (getParentAdditionals().size() == 1) {
398
return getPartialID() + getParentAdditionals().front()->getID();
399
} else {
400
return getPartialID() + (getParentAdditionals().front()->getID() + "->" + getParentAdditionals().back()->getID());
401
}
402
case SUMO_ATTR_FROM:
403
return getParentAdditionals().front()->getID();
404
case SUMO_ATTR_TO:
405
return getParentAdditionals().back()->getID();
406
case GNE_ATTR_DATASET:
407
return myDataIntervalParent->getDataSetParent()->getID();
408
case SUMO_ATTR_BEGIN:
409
return myDataIntervalParent->getAttribute(SUMO_ATTR_BEGIN);
410
case SUMO_ATTR_END:
411
return myDataIntervalParent->getAttribute(SUMO_ATTR_END);
412
default:
413
return getCommonAttribute(key);
414
}
415
}
416
417
418
double
419
GNETAZRelData::getAttributeDouble(SumoXMLAttr key) const {
420
return getCommonAttributeDouble(key);
421
}
422
423
424
void
425
GNETAZRelData::setAttribute(SumoXMLAttr key, const std::string& value, GNEUndoList* undoList) {
426
if (value == getAttribute(key)) {
427
return; //avoid needless changes, later logic relies on the fact that attributes have changed
428
}
429
switch (key) {
430
case SUMO_ATTR_FROM:
431
case SUMO_ATTR_TO:
432
GNEChange_Attribute::changeAttribute(this, key, value, undoList);
433
break;
434
default:
435
setCommonAttribute(key, value, undoList);
436
break;
437
}
438
}
439
440
441
bool
442
GNETAZRelData::isValid(SumoXMLAttr key, const std::string& value) {
443
switch (key) {
444
case SUMO_ATTR_FROM:
445
case SUMO_ATTR_TO:
446
return SUMOXMLDefinitions::isValidNetID(value) &&
447
(myNet->getAttributeCarriers()->retrieveAdditional(SUMO_TAG_TAZ, value, false) != nullptr);
448
default:
449
return isCommonAttributeValid(key, value);
450
}
451
}
452
453
454
bool GNETAZRelData::isAttributeEnabled(SumoXMLAttr key) const {
455
switch (key) {
456
case SUMO_ATTR_ID:
457
return false;
458
default:
459
return true;
460
}
461
}
462
463
464
std::string
465
GNETAZRelData::getPopUpID() const {
466
return getTagStr();
467
}
468
469
470
std::string
471
GNETAZRelData::getHierarchyName() const {
472
if (getParentAdditionals().size() == 1) {
473
return getTagStr() + ": " + getParentAdditionals().front()->getID();
474
} else {
475
return getTagStr() + ": " + getParentAdditionals().front()->getID() + "->" + getParentAdditionals().back()->getID();
476
}
477
}
478
479
480
bool
481
GNETAZRelData::drawTAZRel() const {
482
const auto& inspectedElements = myNet->getViewNet()->getInspectedElements();
483
// first check supermode
484
if (!myNet->getViewNet()->getEditModes().isCurrentSupermodeData()) {
485
return false;
486
}
487
// check TAZRelFrame
488
if (myNet->getViewParent()->getTAZRelDataFrame()->shown()) {
489
// check dataSet
490
const GNEDataSet* dataSet = myNet->getViewParent()->getTAZRelDataFrame()->getDataSetSelector()->getDataSet();
491
if (dataSet && (myDataIntervalParent->getDataSetParent() != dataSet)) {
492
return false;
493
}
494
// check interval
495
const GNEDataInterval* dataInterval = myNet->getViewParent()->getTAZRelDataFrame()->getIntervalSelector()->getDataInterval();
496
if (dataInterval && (myDataIntervalParent != dataInterval)) {
497
return false;
498
}
499
}
500
// check if both draw TAZRel checkBox are disabled
501
if (!myNet->getViewNet()->getDataViewOptions().TAZRelOnlyFrom() && !myNet->getViewNet()->getDataViewOptions().TAZRelOnlyTo()) {
502
return false;
503
}
504
// check if we're inspecting a TAZ
505
if ((myNet->getViewNet()->getEditModes().dataEditMode == DataEditMode::DATA_INSPECT) &&
506
inspectedElements.isInspectingSingleElement() && (inspectedElements.getFirstAC()->getTagProperty()->getTag() == SUMO_TAG_TAZ)) {
507
// ignore TAZRels with one TAZParent
508
if (getParentAdditionals().size() == 2) {
509
if ((getParentAdditionals().front() == inspectedElements.getFirstAC()) &&
510
myNet->getViewNet()->getDataViewOptions().TAZRelOnlyFrom()) {
511
return true;
512
} else if ((getParentAdditionals().back() == inspectedElements.getFirstAC()) &&
513
myNet->getViewNet()->getDataViewOptions().TAZRelOnlyTo()) {
514
return true;
515
} else {
516
return false;
517
}
518
}
519
}
520
return true;
521
}
522
523
524
void
525
GNETAZRelData::setAttribute(SumoXMLAttr key, const std::string& value) {
526
switch (key) {
527
case SUMO_ATTR_FROM: {
528
// replace first TAZ Parent
529
replaceParentTAZElement(0, value);
530
// update geometry
531
updateGeometry();
532
break;
533
}
534
case SUMO_ATTR_TO: {
535
// replace second TAZ Parent
536
replaceParentTAZElement(1, value);
537
// update geometry
538
updateGeometry();
539
break;
540
}
541
default:
542
setCommonAttribute(key, value);
543
if (!isTemplate()) {
544
myDataIntervalParent->getDataSetParent()->updateAttributeColors();
545
}
546
break;
547
}
548
// mark interval toolbar for update
549
if (!isTemplate()) {
550
myNet->getViewNet()->getIntervalBar().markForUpdate();
551
}
552
}
553
554
/****************************************************************************/
555
556