Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
eclipse
GitHub Repository: eclipse/sumo
Path: blob/main/src/netedit/elements/additional/GNEInductionLoopDetector.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 GNEInductionLoopDetector.cpp
15
/// @author Pablo Alvarez Lopez
16
/// @date Nov 2015
17
///
18
//
19
/****************************************************************************/
20
#include <config.h>
21
22
#include <netedit/GNENet.h>
23
#include <netedit/GNETagProperties.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/network/GNETLSEditorFrame.h>
29
#include <utils/gui/div/GLHelper.h>
30
#include <utils/gui/div/GUIGlobalViewObjectsHandler.h>
31
#include <utils/gui/globjects/GUIGLObjectPopupMenu.h>
32
33
#include "GNEInductionLoopDetector.h"
34
#include "GNEAdditionalHandler.h"
35
36
// ===========================================================================
37
// member method definitions
38
// ===========================================================================
39
40
GNEInductionLoopDetector::GNEInductionLoopDetector(GNENet* net) :
41
GNEDetector(net, SUMO_TAG_INDUCTION_LOOP) {
42
}
43
44
45
GNEInductionLoopDetector::GNEInductionLoopDetector(const std::string& id, GNENet* net, const std::string& filename, GNELane* lane,
46
const double pos, const SUMOTime freq, const std::string& outputFilename, const std::vector<std::string>& vehicleTypes,
47
const std::vector<std::string>& nextEdges, const std::string& detectPersons, const std::string& name, const bool friendlyPos,
48
const Parameterised::Map& parameters) :
49
GNEDetector(id, net, filename, SUMO_TAG_INDUCTION_LOOP, pos, freq, lane, outputFilename, vehicleTypes, nextEdges,
50
detectPersons, name, friendlyPos, parameters) {
51
// update centering boundary without updating grid
52
updateCenteringBoundary(false);
53
}
54
55
56
GNEInductionLoopDetector::~GNEInductionLoopDetector() {
57
}
58
59
60
void
61
GNEInductionLoopDetector::writeAdditional(OutputDevice& device) const {
62
device.openTag(getTagProperty()->getTag());
63
device.writeAttr(SUMO_ATTR_ID, getID());
64
device.writeAttr(SUMO_ATTR_LANE, getParentLanes().front()->getID());
65
device.writeAttr(SUMO_ATTR_POSITION, myPositionOverLane);
66
// write common parameters
67
writeDetectorValues(device);
68
// write parameters (Always after children to avoid problems with additionals.xsd)
69
writeParams(device);
70
device.closeTag();
71
}
72
73
74
bool
75
GNEInductionLoopDetector::isAdditionalValid() const {
76
// with friendly position enabled position are "always fixed"
77
if (myFriendlyPosition) {
78
return true;
79
} else {
80
return fabs(myPositionOverLane) <= getParentLanes().front()->getParentEdge()->getNBEdge()->getFinalLength();
81
}
82
}
83
84
85
std::string
86
GNEInductionLoopDetector::getAdditionalProblem() const {
87
// obtain final length
88
const double len = getParentLanes().front()->getParentEdge()->getNBEdge()->getFinalLength();
89
// check if detector has a problem
90
if (GNEAdditionalHandler::checkLanePosition(myPositionOverLane, 0, len, myFriendlyPosition)) {
91
return "";
92
} else {
93
// declare variable for error position
94
std::string errorPosition;
95
// check positions over lane
96
if (myPositionOverLane < 0) {
97
errorPosition = (toString(SUMO_ATTR_POSITION) + " < 0");
98
}
99
if (myPositionOverLane > len) {
100
errorPosition = (toString(SUMO_ATTR_POSITION) + TL(" > lanes's length"));
101
}
102
return errorPosition;
103
}
104
}
105
106
107
void
108
GNEInductionLoopDetector::fixAdditionalProblem() {
109
// declare new position
110
double newPositionOverLane = myPositionOverLane;
111
// fix pos and length checkAndFixDetectorPosition
112
double length = 0;
113
GNEAdditionalHandler::fixLanePosition(newPositionOverLane, length, getParentLanes().front()->getParentEdge()->getNBEdge()->getFinalLength());
114
// set new position
115
setAttribute(SUMO_ATTR_POSITION, toString(newPositionOverLane), myNet->getViewNet()->getUndoList());
116
}
117
118
119
void
120
GNEInductionLoopDetector::updateGeometry() {
121
// update geometry
122
myAdditionalGeometry.updateGeometry(getParentLanes().front()->getLaneShape(), getGeometryPositionOverLane(), myMoveElementLateralOffset);
123
// update centering boundary without updating grid
124
updateCenteringBoundary(false);
125
}
126
127
128
bool
129
GNEInductionLoopDetector::checkDrawRelatedContour() const {
130
// get TLS Attributes
131
const auto& TLSAttributes = myNet->getViewNet()->getViewParent()->getTLSEditorFrame()->getTLSAttributes();
132
// check detectors
133
if (myNet->getViewNet()->selectingDetectorsTLSMode() &&
134
(TLSAttributes->getE1Detectors().count(getParentLanes().front()->getID()) > 0) &&
135
(TLSAttributes->getE1Detectors().at(getParentLanes().front()->getID()) == getID())) {
136
return true;
137
}
138
// check opened popup
139
if (myNet->getViewNet()->getPopup()) {
140
return myNet->getViewNet()->getPopup()->getGLObject() == this;
141
}
142
return false;
143
}
144
145
146
void
147
GNEInductionLoopDetector::drawGL(const GUIVisualizationSettings& s) const {
148
// first check if additional has to be drawn
149
if (myNet->getViewNet()->getDataViewOptions().showAdditionals()) {
150
// Obtain exaggeration of the draw
151
const double E1Exaggeration = getExaggeration(s);
152
// get detail level
153
const auto d = s.getDetailLevel(E1Exaggeration);
154
// draw geometry only if we'rent in drawForObjectUnderCursor mode
155
if (s.checkDrawAdditional(d, isAttributeCarrierSelected())) {
156
// declare colors
157
RGBColor mainColor, secondColor, textColor;
158
// set color
159
if (drawUsingSelectColor()) {
160
mainColor = s.colorSettings.selectedAdditionalColor;
161
secondColor = mainColor.changedBrightness(-32);
162
textColor = mainColor.changedBrightness(32);
163
} else {
164
mainColor = s.detectorSettings.E1Color;
165
secondColor = RGBColor::WHITE;
166
textColor = RGBColor::BLACK;
167
}
168
// draw parent and child lines
169
drawParentChildLines(s, s.additionalSettings.connectionColor);
170
// push layer matrix
171
GLHelper::pushMatrix();
172
// translate to front
173
drawInLayer(GLO_E1DETECTOR);
174
// draw E1 shape
175
drawE1Shape(d, E1Exaggeration, mainColor, secondColor);
176
// draw E1 Logo
177
drawE1DetectorLogo(s, d, E1Exaggeration, "E1", textColor);
178
// pop layer matrix
179
GLHelper::popMatrix();
180
// draw lock icon
181
GNEViewNetHelper::LockIcon::drawLockIcon(d, this, getType(), myAdditionalGeometry.getShape().getCentroid(), E1Exaggeration);
182
// Draw additional ID
183
drawAdditionalID(s);
184
// draw additional name
185
drawAdditionalName(s);
186
// draw dotted contour
187
myAdditionalContour.drawDottedContours(s, d, this, s.dottedContourSettings.segmentWidth, true);
188
}
189
// calculate contour rectangle
190
myAdditionalContour.calculateContourRectangleShape(s, d, this, myAdditionalGeometry.getShape().front(), 2, 1, getType(), 0, 0,
191
myAdditionalGeometry.getShapeRotations().front(), E1Exaggeration, getParentLanes().front()->getParentEdge());
192
}
193
}
194
195
196
std::string
197
GNEInductionLoopDetector::getAttribute(SumoXMLAttr key) const {
198
return getDetectorAttribute(key);
199
}
200
201
202
double
203
GNEInductionLoopDetector::getAttributeDouble(SumoXMLAttr key) const {
204
return getDetectorAttributeDouble(key);
205
}
206
207
208
void
209
GNEInductionLoopDetector::setAttribute(SumoXMLAttr key, const std::string& value, GNEUndoList* undoList) {
210
setDetectorAttribute(key, value, undoList);
211
}
212
213
214
bool
215
GNEInductionLoopDetector::isValid(SumoXMLAttr key, const std::string& value) {
216
return isDetectorValid(key, value);
217
}
218
219
// ===========================================================================
220
// private
221
// ===========================================================================
222
223
void
224
GNEInductionLoopDetector::setAttribute(SumoXMLAttr key, const std::string& value) {
225
setDetectorAttribute(key, value);
226
}
227
228
229
void
230
GNEInductionLoopDetector::setMoveShape(const GNEMoveResult& moveResult) {
231
// change position
232
myPositionOverLane = moveResult.newFirstPos;
233
// set lateral offset
234
myMoveElementLateralOffset = moveResult.firstLaneOffset;
235
// update geometry
236
updateGeometry();
237
}
238
239
240
void
241
GNEInductionLoopDetector::commitMoveShape(const GNEMoveResult& moveResult, GNEUndoList* undoList) {
242
// reset lateral offset
243
myMoveElementLateralOffset = 0;
244
// begin change attribute
245
undoList->begin(this, "position of " + getTagStr());
246
// set startPosition
247
setAttribute(SUMO_ATTR_POSITION, toString(moveResult.newFirstPos), undoList);
248
// check if lane has to be changed
249
if (moveResult.newFirstLane) {
250
// set new lane
251
setAttribute(SUMO_ATTR_LANE, moveResult.newFirstLane->getID(), undoList);
252
}
253
// end change attribute
254
undoList->end();
255
}
256
257
/****************************************************************************/
258
259