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 /*
293 // draw points
294 const RGBColor pointColor = RGBColor::RED;
295 // positions
296 const Position firstPosition = myLanePath.front().first->getLaneShape().positionAtOffset2D(myLanePath.front().second);
297 const Position secondPosition = myLanePath.back().first->getLaneShape().positionAtOffset2D(myLanePath.back().second);
298 // draw geometry points
299 GUIGeometry::drawGeometryPoints(s, nullptr, myFrameParent->getViewNet()->getPositionInformation(), {firstPosition, secondPosition},
300 pointColor, RGBColor::WHITE, s.neteditSizeSettings.polylineWidth, 1, false, true);
301 */
302 // Pop last matrix
304 }
305}
306
307
308void
310 // first check that there is elements
311 if (myLanePath.size() > 0) {
312 // unblock undo/redo
314 // clear lanes
315 clearPath();
316 // disable buttons
317 myFinishCreationButton->disable();
318 myAbortCreationButton->disable();
320 // update info route label
322 // update reachability
324 // update view (to see the new route)
326 }
327}
328
329
330void
332 if (myLanePath.size() > 1) {
333 // remove special color of last selected lane
334 myLanePath.back().first->resetCandidateFlags();
335 // remove last lane
336 myLanePath.pop_back();
337 // change last lane flag
338 if ((myLanePath.size() > 0) && myLanePath.back().first->isSourceCandidate()) {
339 myLanePath.back().first->setSourceCandidate(false);
340 myLanePath.back().first->setTargetCandidate(true);
341 }
342 // enable or disable remove last lane button
343 if (myLanePath.size() > 1) {
345 } else {
347 }
348 // update info route label
350 // update reachability
352 // update view
354 }
355}
356
357
358long
359GNEConsecutiveSelector::onCmdCreatePath(FXObject*, FXSelector, void*) {
361 return 1;
362}
363
364
365long
367 // just call abort path creation
369 return 1;
370}
371
372
373long
375 // just call remove last element
377 return 1;
378}
379
380
381long
383 // recalc frame
384 recalc();
385 // update lane colors (view will be updated within function)
387 return 1;
388}
389
390
392 myFrameParent(nullptr),
393 myAllowOneLane(false) {
394}
395
396
397void
399 if (myLanePath.size() > 0) {
400 // declare variables for route info
401 double length = 0;
402 for (const auto& lane : myLanePath) {
403 length += lane.first->getParentEdge()->getNBEdge()->getLength();
404 }
405 // declare ostringstream for label and fill it
406 std::ostringstream information;
407 information
408 << TL("- Selected lanes: ") << toString(myLanePath.size()) << "\n"
409 << TL("- Length: ") << toString(length);
410 // set new label
411 myInfoPathLabel->setText(information.str().c_str());
412 } else {
413 myInfoPathLabel->setText(TL("No lanes selected"));
414 }
415}
416
417
418void
420 // reset all flags
421 for (const auto& edge : myFrameParent->getViewNet()->getNet()->getAttributeCarriers()->getEdges()) {
422 for (const auto& lane : edge.second->getLanes()) {
423 lane->resetCandidateFlags();
424 }
425 }
426 // clear path
427 myLanePath.clear();
428 // update info route label
430}
431
432/****************************************************************************/
FXDEFMAP(GNEConsecutiveSelector) ConsecutiveLaneSelectorMap[]
@ MID_GNE_SHOWCANDIDATES
enable or disable show path candidates
@ MID_GNE_REMOVELAST
remove last inserted element in path
@ MID_GNE_FINISH
finish lane path creation
Definition GUIAppEnum.h:999
@ MID_GNE_ABORT
abort lane path creation
Definition GUIAppEnum.h:997
#define GUIDesignButton
Definition GUIDesigns.h:88
#define GUIDesignLabelThick(justify)
label extended over frame with thick and with text justify to left
Definition GUIDesigns.h:255
#define GUIDesignCheckButton
checkButton placed in left position
Definition GUIDesigns.h:198
#define GUIDesignLabelFrameInformation
label extended over frame without thick and with text justify to left, used to show information in fr...
Definition GUIDesigns.h:285
@ 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:654
static void popMatrix()
pop matrix
Definition GLHelper.cpp:130
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:347
static void pushMatrix()
push matrix
Definition GLHelper.cpp:117
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:1122
GNEViewNet * getViewNet() const
get view net
Definition GNEFrame.cpp:150
virtual bool createPath(const bool useLastRoute)
create path between two elements
Definition GNEFrame.cpp:304
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:664
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:125
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
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