Eclipse SUMO - Simulation of Urban MObility
Loading...
Searching...
No Matches
GNEConsecutiveSelector.cpp
Go to the documentation of this file.
1/****************************************************************************/
2// Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.dev/sumo
3// Copyright (C) 2001-2024 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/****************************************************************************/
18// Consecutive lane selector module
19/****************************************************************************/
20#include <config.h>
21
23#include <netedit/GNENet.h>
24#include <netedit/GNEViewNet.h>
31
33#include "GNEFrame.h"
34
35
36// ===========================================================================
37// FOX callback mapping
38// ===========================================================================
39
46
47// Object implementation
48FXIMPLEMENT(GNEConsecutiveSelector, MFXGroupBoxModule, ConsecutiveLaneSelectorMap, ARRAYNUMBER(ConsecutiveLaneSelectorMap))
49
50// ---------------------------------------------------------------------------
51// GNEConsecutiveSelector - methods
52// ---------------------------------------------------------------------------
53
54GNEConsecutiveSelector::GNEConsecutiveSelector(GNEFrame* frameParent, const bool allowOneLane) :
55 MFXGroupBoxModule(frameParent, TL("Consecutive lane selector")),
56 myFrameParent(frameParent),
57 myAllowOneLane(allowOneLane) {
58 // create label for route info
59 myInfoPathLabel = new FXLabel(getCollapsableFrame(), TL("No lanes selected"), 0, GUIDesignLabelThick(JUSTIFY_LEFT));
60 // create button for finish route creation
61 myFinishCreationButton = GUIDesigns::buildFXButton(getCollapsableFrame(), TL("Finish path creation"), "", "", nullptr, this, MID_GNE_FINISH, GUIDesignButton);
62 myFinishCreationButton->disable();
63 // create button for abort route creation
64 myAbortCreationButton = GUIDesigns::buildFXButton(getCollapsableFrame(), TL("Abort path creation"), "", "", nullptr, this, MID_GNE_ABORT, GUIDesignButton);
65 myAbortCreationButton->disable();
66 // create button for remove last inserted lane
67 myRemoveLastInsertedElement = GUIDesigns::buildFXButton(getCollapsableFrame(), TL("Remove last lane"), "", "", nullptr, this, MID_GNE_REMOVELAST, GUIDesignButton);
68 myRemoveLastInsertedElement->disable();
69 // create check button
70 myShowCandidateLanes = new FXCheckButton(getCollapsableFrame(), TL("Show candidate lanes"), this, MID_GNE_SHOWCANDIDATES, GUIDesignCheckButton);
71 myShowCandidateLanes->setCheck(TRUE);
72 // create information label
73 new FXLabel(this, (TL("-BACKSPACE: undo click") + std::string("\n") + TL("-ESC: Abort path creation")).c_str(), 0, GUIDesignLabelFrameInformation);
74}
75
76
78
79
80void
82 // first abort creation
84 // disable buttons
85 myFinishCreationButton->disable();
86 myAbortCreationButton->disable();
88 // update lane colors
90 // recalc before show (to avoid graphic problems)
91 recalc();
92 // show modul
93 show();
94}
95
96
97void
99 // clear path
100 clearPath();
101 // hide modul
102 hide();
103}
104
105
106const std::vector<std::pair<GNELane*, double> >&
110
111
112const std::vector<std::string>
114 std::vector<std::string> laneIDs;
115 for (const auto& lane : myLanePath) {
116 if (laneIDs.empty() || (laneIDs.back() != lane.first->getID())) {
117 laneIDs.push_back(lane.first->getID());
118 }
119 }
120 return laneIDs;
121}
122
123
124bool
126 // first check if lane is valid
127 if (lane == nullptr) {
128 return false;
129 }
130 // check candidate lane
131 if ((myShowCandidateLanes->getCheck() == TRUE) && !lane->isPossibleCandidate()) {
132 if (lane->isSpecialCandidate() || lane->isConflictedCandidate()) {
133 // Write warning
134 WRITE_WARNING(TL("Invalid lane"));
135 // abort add lane
136 return false;
137 }
138 }
139 // get mouse position
141 // calculate lane offset
142 const double posOverLane = lane->getLaneShape().nearest_offset_to_point2D(mousePos);
143 // All checks ok, then add it in selected elements
144 if (myLanePath.empty()) {
145 myLanePath.push_back(std::make_pair(lane, posOverLane));
146 } else if ((myLanePath.size() == 1) && (myLanePath.front().first == lane)) {
147 if (myAllowOneLane) {
148 myLanePath.push_back(std::make_pair(lane, posOverLane));
149 } else {
150 // Write warning
151 WRITE_WARNING(TL("Lane path needs at least two lanes"));
152 // abort add lane
153 return false;
154 }
155 } else if (myLanePath.back().first == lane) {
156 // only change last position
157 myLanePath.back().second = posOverLane;
158 } else {
159 myLanePath.push_back(std::make_pair(lane, posOverLane));
160 // special case if we clicked over a new lane after a previous double lane
161 if ((myLanePath.size() == 3) && (myLanePath.at(0).first == myLanePath.at(1).first)) {
162 // remove second lane
163 myLanePath.erase(myLanePath.begin() + 1);
164 }
165 }
166 // enable abort route button
167 myAbortCreationButton->enable();
168 // enable finish button
169 myFinishCreationButton->enable();
170 // disable undo/redo temporally
172 // enable or disable remove last lane button
173 if (myLanePath.size() > 1) {
175 } else {
177 }
178 // update info route label
180 // update lane colors
182 return true;
183}
184
185
186bool
190
191
192void
194 // reset all flags
195 for (const auto& edge : myFrameParent->getViewNet()->getNet()->getAttributeCarriers()->getEdges()) {
196 for (const auto& lane : edge.second->getLanes()) {
197 lane->resetCandidateFlags();
198 }
199 }
200 // set reachability
201 if (myLanePath.size() > 0 && (myShowCandidateLanes->getCheck() == TRUE)) {
202 // first mark all lanes as invalid
203 for (const auto& edge : myFrameParent->getViewNet()->getNet()->getAttributeCarriers()->getEdges()) {
204 for (const auto& lane : edge.second->getLanes()) {
205 lane->setConflictedCandidate(true);
206 }
207 }
208 // now mark lane paths as valid
209 for (const auto& lane : myLanePath) {
210 // disable conflicted candidate
211 lane.first->setConflictedCandidate(false);
212 if (lane == myLanePath.back()) {
213 lane.first->setSourceCandidate(true);
214 } else {
215 lane.first->setTargetCandidate(true);
216 }
217 }
218 // get parent edge
219 const GNEEdge* edge = myLanePath.back().first->getParentEdge();
220 // iterate over connections
221 for (const auto& connection : edge->getGNEConnections()) {
222 // mark possible candidates
223 if (connection->getLaneFrom() == myLanePath.back().first) {
224 connection->getLaneTo()->setConflictedCandidate(false);
225 connection->getLaneTo()->setPossibleCandidate(true);
226 }
227 }
228 }
229 // update view net
231}
232
233
234void
236 // Only draw if there is at least one lane
237 if (myLanePath.size() > 0) {
238 // get widths
239 const double lineWidth = 0.35;
240 const double lineWidthin = 0.25;
241 // declare vector with shapes
242 std::vector<PositionVector> shapes;
243 // iterate over lanes (only if there is more than one)
244 if ((myLanePath.size() == 2) && (myLanePath.front().first == myLanePath.back().first)) {
245 // only add first lane shape
246 shapes.push_back(myLanePath.front().first->getLaneShape());
247 // adjust shape
248 shapes.front() = shapes.front().getSubpart(myLanePath.front().second, myLanePath.back().second);
249 } else if (myLanePath.size() > 1) {
250 // get shapes
251 for (int i = 0; i < (int)myLanePath.size(); i++) {
252 // get lane
253 const GNELane* lane = myLanePath.at(i).first;
254 // add lane shape
255 shapes.push_back(lane->getLaneShape());
256 // draw connection between lanes
257 if ((i + 1) < (int)myLanePath.size()) {
258 // get next lane
259 const GNELane* nextLane = myLanePath.at(i + 1).first;
260 if (lane->getLane2laneConnections().exist(nextLane)) {
261 shapes.push_back(lane->getLane2laneConnections().getLane2laneGeometry(nextLane).getShape());
262 } else {
263 shapes.push_back({lane->getLaneShape().back(), nextLane->getLaneShape().front()});
264 }
265 }
266 }
267 // adjust first and last shape
268 shapes.front() = shapes.front().splitAt(myLanePath.front().second).second;
269 shapes.back() = shapes.back().splitAt(myLanePath.back().second).first;
270 }
271 // Add a draw matrix
273 // move to temporal shape
274 glTranslated(0, 0, GLO_TEMPORALSHAPE);
275 // iterate over shapes
276 for (const auto& shape : shapes) {
277 // set extern
279 // draw extern shape
280 GLHelper::drawBoxLines(shape, lineWidth);
281 // push matrix
283 // move to front
284 glTranslated(0, 0, 0.1);
285 // set orange color
287 // draw intern shape
288 GLHelper::drawBoxLines(shape, lineWidthin);
289 // Pop matrix
291 }
292 // draw points
293 if (shapes.size() > 0) {
294 // draw geometry points
296 {shapes.front().front(), shapes.back().back()}, RGBColor::RED,
297 myFrameParent->getViewNet()->getVisualisationSettings().neteditSizeSettings.additionalGeometryPointRadius, 1, false);
298 }
299 // Pop last matrix
301 }
302}
303
304
305void
307 // first check that there is elements
308 if (myLanePath.size() > 0) {
309 // unblock undo/redo
311 // clear lanes
312 clearPath();
313 // disable buttons
314 myFinishCreationButton->disable();
315 myAbortCreationButton->disable();
317 // update info route label
319 // update reachability
321 // update view (to see the new route)
323 }
324}
325
326
327void
329 if (myLanePath.size() > 1) {
330 // remove special color of last selected lane
331 myLanePath.back().first->resetCandidateFlags();
332 // remove last lane
333 myLanePath.pop_back();
334 // change last lane flag
335 if ((myLanePath.size() > 0) && myLanePath.back().first->isSourceCandidate()) {
336 myLanePath.back().first->setSourceCandidate(false);
337 myLanePath.back().first->setTargetCandidate(true);
338 }
339 // enable or disable remove last lane button
340 if (myLanePath.size() > 1) {
342 } else {
344 }
345 // update info route label
347 // update reachability
349 // update view
351 }
352}
353
354
355long
356GNEConsecutiveSelector::onCmdCreatePath(FXObject*, FXSelector, void*) {
358 return 1;
359}
360
361
362long
364 // just call abort path creation
366 return 1;
367}
368
369
370long
372 // just call remove last element
374 return 1;
375}
376
377
378long
380 // recalc frame
381 recalc();
382 // update lane colors (view will be updated within function)
384 return 1;
385}
386
387
389 myFrameParent(nullptr),
390 myAllowOneLane(false) {
391}
392
393
394void
396 if (myLanePath.size() > 0) {
397 // declare variables for route info
398 double length = 0;
399 for (const auto& lane : myLanePath) {
400 length += lane.first->getParentEdge()->getNBEdge()->getLength();
401 }
402 // declare ostringstream for label and fill it
403 std::ostringstream information;
404 information
405 << TL("- Selected lanes: ") << toString(myLanePath.size()) << "\n"
406 << TL("- Length: ") << toString(length);
407 // set new label
408 myInfoPathLabel->setText(information.str().c_str());
409 } else {
410 myInfoPathLabel->setText(TL("No lanes selected"));
411 }
412}
413
414
415void
417 // reset all flags
418 for (const auto& edge : myFrameParent->getViewNet()->getNet()->getAttributeCarriers()->getEdges()) {
419 for (const auto& lane : edge.second->getLanes()) {
420 lane->resetCandidateFlags();
421 }
422 }
423 // clear path
424 myLanePath.clear();
425 // update info route label
427}
428
429/****************************************************************************/
FXDEFMAP(GNEConsecutiveSelector) ConsecutiveLaneSelectorMap[]
@ MID_GNE_SHOWCANDIDATES
enable or disable show path candidates
Definition GUIAppEnum.h:997
@ MID_GNE_REMOVELAST
remove last inserted element in path
Definition GUIAppEnum.h:995
@ MID_GNE_FINISH
finish lane path creation
Definition GUIAppEnum.h:993
@ MID_GNE_ABORT
abort lane path creation
Definition GUIAppEnum.h:991
#define GUIDesignButton
Definition GUIDesigns.h:82
#define GUIDesignLabelThick(justify)
label extended over frame with thick and with text justify to left
Definition GUIDesigns.h:249
#define GUIDesignCheckButton
checkButton placed in left position
Definition GUIDesigns.h:192
#define GUIDesignLabelFrameInformation
label extended over frame without thick and with text justify to left, used to show information in fr...
Definition GUIDesigns.h:279
@ GLO_TEMPORALSHAPE
temporal shape (used in netedit)
#define WRITE_WARNING(msg)
Definition MsgHandler.h:295
#define TL(string)
Definition MsgHandler.h:315
std::string toString(const T &t, std::streamsize accuracy=gPrecision)
Definition ToString.h:46
static void setColor(const RGBColor &c)
Sets the gl-color to this value.
Definition GLHelper.cpp:649
static void popMatrix()
pop matrix
Definition GLHelper.cpp:131
static void drawBoxLines(const PositionVector &geom, const std::vector< double > &rots, const std::vector< double > &lengths, double width, int cornerDetail=0, double offset=0)
Draws thick lines.
Definition GLHelper.cpp:348
static void pushMatrix()
push matrix
Definition GLHelper.cpp:118
void enableUndoRedoTemporally()
enable undo-redo temporally (for example, after creating an edge)
void disableUndoRedoTemporally(const std::string &reason)
disable undo-redo temporally giving a string with the reason (for example, if we're creating an edge)
bool isSpecialCandidate() const
check if this element is a special candidate
bool isPossibleCandidate() const
check if this element is a possible candidate
bool isConflictedCandidate() const
check if this element is a conflicted candidate
void setConflictedCandidate(const bool value)
set element as conflicted candidate
std::vector< std::pair< GNELane *, double > > myLanePath
vector with lanes and clicked positions
void drawTemporalConsecutiveLanePath() const
draw temporal consecutive lane path
bool addLane(GNELane *lane)
add lane
void abortPathCreation()
abort path creation
FXLabel * myInfoPathLabel
label with path info
GNEFrame * myFrameParent
pointer to frame parent
const bool myAllowOneLane
allow one lane
void updateLaneColors()
update lane colors
void showConsecutiveLaneSelectorModule()
show GNEConsecutiveSelector
long onCmdCreatePath(FXObject *, FXSelector, void *)
void clearPath()
clear lanes (and restore colors)
FXButton * myRemoveLastInsertedElement
button for removing last inserted element
FXCheckButton * myShowCandidateLanes
CheckBox for show candidate lanes.
long onCmdRemoveLastElement(FXObject *, FXSelector, void *)
Called when the user click over button "Remove las inserted lane".
void updateInfoRouteLabel()
update InfoRouteLabel
const std::vector< std::pair< GNELane *, double > > & getLanePath() const
get vector with lanes and clicked positions
void removeLastElement()
remove path element
bool drawCandidateLanesWithSpecialColor() const
draw candidate lanes with special color (Only for candidates, special and conflicted)
void hideConsecutiveLaneSelectorModule()
show GNEConsecutiveSelector
long onCmdShowCandidateLanes(FXObject *, FXSelector, void *)
Called when the user click over check button "show candidate lanes".
const std::vector< std::string > getLaneIDPath() const
get lane IDs
FXButton * myFinishCreationButton
button for finish route creation
long onCmdAbortPathCreation(FXObject *, FXSelector, void *)
Called when the user click over button "Abort route creation".
FXButton * myAbortCreationButton
button for abort route creation
A road/street connecting two junctions (netedit-version)
Definition GNEEdge.h:53
const std::vector< GNEConnection * > & getGNEConnections() const
returns a reference to the GNEConnection vector
Definition GNEEdge.cpp:1124
GNEViewNet * getViewNet() const
get view net
Definition GNEFrame.cpp:150
virtual bool createPath(const bool useLastRoute)
create path between two elements
Definition GNEFrame.cpp:298
bool exist(const GNELane *toLane) const
check if exist a lane2lane geometry for the given toLane
const GUIGeometry & getLane2laneGeometry(const GNELane *toLane) const
get lane2lane geometry
This lane is powered by an underlying GNEEdge and basically knows how to draw itself.
Definition GNELane.h:46
const PositionVector & getLaneShape() const
get elements shape
Definition GNELane.cpp:214
const GNELane2laneConnection & getLane2laneConnections() const
get Lane2laneConnection struct
Definition GNELane.cpp:662
const std::map< std::string, GNEEdge * > & getEdges() const
map with the ID and pointer to edges of net
GNENetHelper::AttributeCarriers * getAttributeCarriers() const
get all attribute carriers used in this net
Definition GNENet.cpp:127
GNENet * getNet() const
get the net object
GNEViewParent * getViewParent() const
get the net object
void updateViewNet(const bool ignoreViewUpdater=true) const
Mark the entire GNEViewNet to be repainted later.
GNEApplicationWindow * getGNEAppWindows() const
get GNE Application Windows
static FXButton * buildFXButton(FXComposite *p, const std::string &text, const std::string &tip, const std::string &help, FXIcon *ic, FXObject *tgt, FXSelector sel, FXuint opts=BUTTON_NORMAL, FXint x=0, FXint y=0, FXint w=0, FXint h=0, FXint pl=DEFAULT_PAD, FXint pr=DEFAULT_PAD, FXint pt=DEFAULT_PAD, FXint pb=DEFAULT_PAD)
build button
static void drawGeometryPoints(const GUIVisualizationSettings::Detail d, const PositionVector &shape, const RGBColor &color, const double radius, const double exaggeration, const bool editingElevation)
draw geometry points
const PositionVector & getShape() const
The shape of the additional element.
Position snapToActiveGrid(const Position &pos, bool snapXY=true) const
Returns a position that is mapped to the closest grid point if the grid is active.
virtual Position getPositionInformation() const
Returns the cursor's x/y position within the network.
MFXGroupBoxModule (based on FXGroupBox)
A point in 2D or 3D with translation and scaling methods.
Definition Position.h:37
double nearest_offset_to_point2D(const Position &p, bool perpendicular=true) const
return the nearest offest to point 2D
static const RGBColor GREY
Definition RGBColor.h:194
static const RGBColor ORANGE
Definition RGBColor.h:191
static const RGBColor RED
named colors
Definition RGBColor.h:185