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-2023 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 = new FXButton(getCollapsableFrame(), TL("Finish path creation"), nullptr, this, MID_GNE_FINISH, GUIDesignButton);
62 myFinishCreationButton->disable();
63 // create button for abort route creation
64 myAbortCreationButton = new FXButton(getCollapsableFrame(), TL("Abort path creation"), nullptr, this, MID_GNE_ABORT, GUIDesignButton);
65 myAbortCreationButton->disable();
66 // create button for remove last inserted lane
67 myRemoveLastInsertedElement = new FXButton(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
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 const RGBColor pointColor = RGBColor::RED;
294 // positions
295 const Position firstPosition = myLanePath.front().first->getLaneShape().positionAtOffset2D(myLanePath.front().second);
296 const Position secondPosition = myLanePath.back().first->getLaneShape().positionAtOffset2D(myLanePath.back().second);
297 // draw geometry points
298 GUIGeometry::drawGeometryPoints(s, myFrameParent->getViewNet()->getPositionInformation(), {firstPosition, secondPosition},
299 pointColor, RGBColor::WHITE, s.neteditSizeSettings.polylineWidth, 1, false, true);
300 // Pop last matrix
302 }
303}
304
305
306void
308 // first check that there is elements
309 if (myLanePath.size() > 0) {
310 // unblock undo/redo
312 // clear lanes
313 clearPath();
314 // disable buttons
315 myFinishCreationButton->disable();
316 myAbortCreationButton->disable();
318 // update info route label
320 // update reachability
322 // update view (to see the new route)
324 }
325}
326
327
328void
330 if (myLanePath.size() > 1) {
331 // remove special color of last selected lane
332 myLanePath.back().first->resetCandidateFlags();
333 // remove last lane
334 myLanePath.pop_back();
335 // change last lane flag
336 if ((myLanePath.size() > 0) && myLanePath.back().first->isSourceCandidate()) {
337 myLanePath.back().first->setSourceCandidate(false);
338 myLanePath.back().first->setTargetCandidate(true);
339 }
340 // enable or disable remove last lane button
341 if (myLanePath.size() > 1) {
343 } else {
345 }
346 // update info route label
348 // update reachability
350 // update view
352 }
353}
354
355
356long
357GNEConsecutiveSelector::onCmdCreatePath(FXObject*, FXSelector, void*) {
359 return 1;
360}
361
362
363long
365 // just call abort path creation
367 return 1;
368}
369
370
371long
373 // just call remove last element
375 return 1;
376}
377
378
379long
381 // recalc frame
382 recalc();
383 // update lane colors (view will be updated within function)
385 return 1;
386}
387
388
390 myFrameParent(nullptr),
391 myAllowOneLane(false) {
392}
393
394
395void
397 if (myLanePath.size() > 0) {
398 // declare variables for route info
399 double length = 0;
400 for (const auto& lane : myLanePath) {
401 length += lane.first->getParentEdge()->getNBEdge()->getLength();
402 }
403 // declare ostringstream for label and fill it
404 std::ostringstream information;
405 information
406 << TL("- Selected lanes: ") << toString(myLanePath.size()) << "\n"
407 << TL("- Length: ") << toString(length);
408 // set new label
409 myInfoPathLabel->setText(information.str().c_str());
410 } else {
411 myInfoPathLabel->setText(TL("No lanes selected"));
412 }
413}
414
415
416void
418 // reset all flags
419 for (const auto& edge : myFrameParent->getViewNet()->getNet()->getAttributeCarriers()->getEdges()) {
420 for (const auto& lane : edge.second->getLanes()) {
421 lane->resetCandidateFlags();
422 }
423 }
424 // clear path
425 myLanePath.clear();
426 // update info route label
428}
429
430/****************************************************************************/
FXDEFMAP(GNEConsecutiveSelector) ConsecutiveLaneSelectorMap[]
@ MID_GNE_SHOWCANDIDATES
enable or disable show path candidates
Definition GUIAppEnum.h:967
@ MID_GNE_REMOVELAST
remove last inserted element in path
Definition GUIAppEnum.h:965
@ MID_GNE_FINISH
finish lane path creation
Definition GUIAppEnum.h:963
@ MID_GNE_ABORT
abort lane path creation
Definition GUIAppEnum.h:961
#define GUIDesignButton
Definition GUIDesigns.h:74
#define GUIDesignLabelThick(justify)
label extended over frame with thick and with text justify to left
Definition GUIDesigns.h:244
#define GUIDesignCheckButton
checkButton placed in left position
Definition GUIDesigns.h:187
#define GUIDesignLabelFrameInformation
label extended over frame without thick and with text justify to left, used to show information in fr...
Definition GUIDesigns.h:274
@ GLO_TEMPORALSHAPE
temporal shape (used in netedit)
#define WRITE_WARNING(msg)
Definition MsgHandler.h:270
#define TL(string)
Definition MsgHandler.h:287
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:583
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:329
static void pushMatrix()
push matrix
Definition GLHelper.cpp:117
void disableUndoRedo(const std::string &reason)
disable undo-redo giving a string with the reason
void enableUndoRedo()
disable undo-redo
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
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
void drawTemporalConsecutiveLanePath(const GUIVisualizationSettings &s) const
draw temporal consecutive lane path
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:846
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:136
const GNELane2laneConnection & getLane2laneConnections() const
get Lane2laneConnection struct
Definition GNELane.cpp:829
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:120
GNENet * getNet() const
get the net object
GNEViewParent * getViewParent() const
get the net object
void updateViewNet() const
Mark the entire GNEViewNet to be repainted later.
GNEApplicationWindow * getGNEAppWindows() const
get GNE Application Windows
static void drawGeometryPoints(const GUIVisualizationSettings &s, const Position &mousePos, const PositionVector &shape, const RGBColor &geometryPointColor, const RGBColor &textColor, const double radius, const double exaggeration, const bool editingElevation, const bool drawExtremeSymbols)
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.
Stores the information about how to visualize structures.
GUIVisualizationNeteditSizeSettings neteditSizeSettings
netedit size settings
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 WHITE
Definition RGBColor.h:192
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
static const double polylineWidth
poly line width