Eclipse SUMO - Simulation of Urban MObility
Loading...
Searching...
No Matches
GNELane.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-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/****************************************************************************/
19// A class for visualizing Lane geometry (adapted from GNELaneWrapper)
20/****************************************************************************/
21
22#include <netbuild/NBEdgeCont.h>
23#include <netedit/GNENet.h>
24#include <netedit/GNEUndoList.h>
25#include <netedit/GNEViewNet.h>
50
51#include "GNELane.h"
52#include "GNEInternalLane.h"
53#include "GNEConnection.h"
54#include "GNEEdgeTemplate.h"
55
56// ===========================================================================
57// FOX callback mapping
58// ===========================================================================
59
60// Object implementation
61FXIMPLEMENT(GNELane, FXDelegator, 0, 0)
62
63// ===========================================================================
64// method definitions
65// ===========================================================================
66
67// ---------------------------------------------------------------------------
68// GNELane::LaneDrawingConstants - methods
69// ---------------------------------------------------------------------------
70
72 myLane(lane) {
73}
74
75
76void
78 // get NBEdge
79 const auto& NBEdge = myLane->getParentEdge()->getNBEdge();
80 // get lane struct
81 const auto& laneStruct = myLane->getParentEdges().front()->getNBEdge()->getLaneStruct(myLane->getIndex());
82 // get selection scale
83 const double selectionScale = myLane->isAttributeCarrierSelected() || myLane->getParentEdges().front()->isAttributeCarrierSelected() ? s.selectorFrameScale : 1;
84 // get lane width
85 const double laneWidth = (laneStruct.width == -1 ? SUMO_const_laneWidth : laneStruct.width);
86 // calculate exaggeration
87 myExaggeration = selectionScale * s.laneWidthExaggeration;
88 // get detail level
90 // check if draw lane as railway
91 myDrawAsRailway = isRailway(laneStruct.permissions) && ((laneStruct.permissions & SVC_BUS) == 0) && s.showRails;
92 // adjust rest of parameters depending if draw as railway
93 if (myDrawAsRailway) {
94 // draw as railway: assume standard gauge of 1435mm when lane width is not set
95 myDrawingWidth = (laneWidth == SUMO_const_laneWidth ? 1.4350 : laneWidth) * myExaggeration;
96 // calculate internal drawing width
98 } else {
99 // calculate exaggerated drawing width
100 myDrawingWidth = laneWidth * myExaggeration * 0.5;
101 // calculate internal drawing width
103 }
104 // check if draw superposed
106 // adjust parameters depending of superposing
107 if (myDrawSuperposed) {
108 // apply offset
109 myOffset = myDrawingWidth * 0.5;
110 // reduce width
111 myDrawingWidth *= 0.4;
113 } else {
114 // restore offset
115 myOffset = 0;
116 }
117}
118
119
120double
122 return myExaggeration;
123}
124
125
126double
128 return myDrawingWidth;
129}
130
131
132double
134 return myInternalDrawingWidth;
135}
136
137
138double
140 return myOffset;
141}
142
143
146 return myDetail;
147}
148
149
150bool
152 return myDrawAsRailway;
153}
154
155
156bool
158 return myDrawSuperposed;
159}
160
161
162// ---------------------------------------------------------------------------
163// GNELane - methods
164// ---------------------------------------------------------------------------
165#ifdef _MSC_VER
166#pragma warning(push)
167#pragma warning(disable: 4355) // mask warning about "this" in initializers
168#endif
169GNELane::GNELane(GNEEdge* edge, const int index) :
170 GNENetworkElement(edge->getNet(), edge->getNBEdge()->getLaneID(index), SUMO_TAG_LANE),
171 myIndex(index),
173 mySpecialColor(nullptr),
176 // set parents
177 setParent<GNEEdge*>(edge);
178 // update centering boundary without updating grid
180}
181
182
184 GNENetworkElement(nullptr, "dummyConstructorGNELane", SUMO_TAG_LANE),
185 myIndex(-1),
186 myDrawingConstants(nullptr),
187 mySpecialColor(nullptr),
188 mySpecialColorValue(-1),
189 myLane2laneConnections(this) {
190}
191#ifdef _MSC_VER
192#pragma warning(pop)
193#endif
194
196 if (myDrawingConstants) {
197 delete myDrawingConstants;
198 }
199}
200
201
202GNEEdge*
204 return getParentEdges().front();
205}
206
207
208bool
210 return (getParentEdges().front()->getNBEdge()->getPermissions(myIndex) & SVC_PEDESTRIAN) > 0;
211}
212
213
214const GUIGeometry&
216 return myLaneGeometry;
217}
218
219
220const PositionVector&
222 if (getParentEdges().front()->getNBEdge()->getLaneStruct(myIndex).customShape.size() > 0) {
223 return getParentEdges().front()->getNBEdge()->getLaneStruct(myIndex).customShape;
224 } else {
225 return getParentEdges().front()->getNBEdge()->getLaneShape(myIndex);
226 }
227}
228
229
230const std::vector<double>&
234
235
236const std::vector<double>&
240
241
246
247
248void
250 // Clear texture containers
253 // get lane shape and extend if is too short
254 auto laneShape = getLaneShape();
255 if (laneShape.length2D() < 1) {
256 laneShape.extrapolate2D(1 - laneShape.length2D());
257 }
258 // Obtain lane shape of NBEdge
260 // update connections
262 // update additionals children associated with this lane
263 for (const auto& additional : getParentAdditionals()) {
264 additional->updateGeometry();
265 }
266 // update additionals parents associated with this lane
267 for (const auto& additional : getChildAdditionals()) {
268 additional->updateGeometry();
269 }
270 // update partial demand elements parents associated with this lane
271 for (const auto& demandElement : getParentDemandElements()) {
272 demandElement->updateGeometry();
273 }
274 // update partial demand elements children associated with this lane
275 for (const auto& demandElement : getChildDemandElements()) {
276 demandElement->updateGeometry();
277 }
278 // Update geometry of parent generic datas that have this edge as parent
279 for (const auto& additionalParent : getParentGenericDatas()) {
280 additionalParent->updateGeometry();
281 }
282 // Update geometry of additionals generic datas vinculated to this edge
283 for (const auto& childAdditionals : getChildGenericDatas()) {
284 childAdditionals->updateGeometry();
285 }
286 // compute geometry of path elements elements vinculated with this lane (depending of showDemandElements)
288 for (const auto& childAdditional : getChildAdditionals()) {
289 childAdditional->computePathElement();
290 }
291 for (const auto& childDemandElement : getChildDemandElements()) {
292 childDemandElement->computePathElement();
293 }
294 for (const auto& childGenericData : getChildGenericDatas()) {
295 childGenericData->computePathElement();
296 }
297 }
298 // in Move mode, connections aren't updated
300 // Update incoming connections of this lane
301 const auto incomingConnections = getGNEIncomingConnections();
302 for (const auto& connection : incomingConnections) {
303 connection->updateGeometry();
304 }
305 // Update outgoings connections of this lane
306 const auto outGoingConnections = getGNEOutcomingConnections();
307 for (const auto& connection : outGoingConnections) {
308 connection->updateGeometry();
309 }
310 }
311 // if lane has enought length for show textures of restricted lanes
312 if ((getLaneShapeLength() > 4)) {
313 // if lane is restricted
315 // get values for position and rotation of icons
316 for (int i = 2; i < getLaneShapeLength() - 1; i += 15) {
319 }
320 }
321 }
322}
323
324
327 return getLaneShape().positionAtOffset2D(getLaneShape().length2D() * 0.5);
328}
329
330
331bool
333 const auto& inspectedElements = myNet->getViewNet()->getInspectedElements();
334 // check if we're inspecting a connection
335 if (inspectedElements.isInspectingSingleElement() && (inspectedElements.getFirstAC()->getTagProperty()->getTag() == SUMO_TAG_CONNECTION) &&
336 inspectedElements.getFirstAC()->getAttribute(GNE_ATTR_FROM_LANEID) == getID()) {
337 return true;
338 } else {
339 return false;
340 }
341}
342
343
344bool
346 const auto& inspectedElements = myNet->getViewNet()->getInspectedElements();
347 // check if we're inspecting a connection
348 if (inspectedElements.isInspectingSingleElement() && (inspectedElements.getFirstAC()->getTagProperty()->getTag() == SUMO_TAG_CONNECTION) &&
349 inspectedElements.getFirstAC()->getAttribute(GNE_ATTR_TO_LANEID) == getID()) {
350 return true;
351 } else {
352 return false;
353 }
354}
355
356
357bool
359 // check opened popup
360 if (myNet->getViewNet()->getPopup()) {
361 return myNet->getViewNet()->getPopup()->getGLObject() == this;
362 }
363 return false;
364}
365
366
367bool
369 // get modes and viewParent (for code legibility)
370 const auto& modes = myNet->getViewNet()->getEditModes();
371 const auto& viewParent = myNet->getViewNet()->getViewParent();
372 // check if we're selecting edges in additional mode
373 if (modes.isCurrentSupermodeNetwork() && (modes.networkEditMode == NetworkEditMode::NETWORK_ADDITIONAL)) {
374 if (viewParent->getAdditionalFrame()->getViewObjetsSelector()->isNetworkElementSelected(this)) {
375 return true;
376 } else if (viewParent->getAdditionalFrame()->getViewObjetsSelector()->getTag() == myTagProperty->getTag()) {
378 } else {
379 return false;
380 }
381 } else {
382 return false;
383 }
384}
385
386
387bool
389 // first check if we're selecting edges or lanes
391 return false;
392 } else {
393 // get edit modes
394 const auto& editModes = myNet->getViewNet()->getEditModes();
395 // check if we're in delete mode
396 if (editModes.isCurrentSupermodeNetwork() && (editModes.networkEditMode == NetworkEditMode::NETWORK_DELETE)) {
398 } else {
399 return false;
400 }
401 }
402}
403
404
405bool
407 return false;
408}
409
410
411bool
413 // first check if we're selecting edges or lanes
415 return false;
416 } else {
417 // get edit modes
418 const auto& editModes = myNet->getViewNet()->getEditModes();
419 // check if we're in select mode
420 if (editModes.isCurrentSupermodeNetwork() && (editModes.networkEditMode == NetworkEditMode::NETWORK_SELECT)) {
422 } else {
423 return false;
424 }
425 }
426}
427
428
429bool
431 // check if we're editing this network element
433 if (editedNetworkElement) {
434 return editedNetworkElement == this;
435 } else {
436 return false;
437 }
438}
439
440
443 // edit depending if shape is being edited
444 if (isShapeEdited()) {
445 // calculate move shape operation
446 return calculateMoveShapeOperation(this, getLaneShape(), false);
447 } else {
448 return nullptr;
449 }
450}
451
452
453void
454GNELane::removeGeometryPoint(const Position clickedPosition, GNEUndoList* undoList) {
455 // edit depending if shape is being edited
456 if (isShapeEdited()) {
457 // get original shape
459 // check shape size
460 if (shape.size() > 2) {
461 // obtain index
462 int index = shape.indexOfClosest(clickedPosition);
463 // get snap radius
465 // check if we have to create a new index
466 if ((index != -1) && shape[index].distanceSquaredTo2D(clickedPosition) < (snap_radius * snap_radius)) {
467 // remove geometry point
468 shape.erase(shape.begin() + index);
469 // commit new shape
470 undoList->begin(this, "remove geometry point of " + getTagStr());
472 undoList->end();
473 }
474 }
475 }
476}
477
478
479void
481 // update lane drawing constan
483 // calculate layer
484 double layer = GLO_LANE;
485 if (getParentEdges().front()->isMarkedForDrawingFront()) {
486 layer = GLO_FRONTELEMENT;
488 layer = GLO_JUNCTION + 2;
489 }
490 // check drawing conditions
492 // draw lane
493 drawLane(s, layer);
494 // draw lock icon
496 // draw dotted contour
498 }
499 // calculate contour (always before children)
500 calculateLaneContour(s, layer);
501 // draw children
502 drawChildren(s);
503}
504
505
506void
508 // Check if edge can be deleted
510 myNet->deleteLane(this, myNet->getViewNet()->getUndoList(), false);
511 }
512}
513
514
515void
519
520
521
524 // first obtain edit mode (needed because certain Commands depend of current edit mode)
526 // get mouse position
527 const auto mousePosition = myNet->getViewNet()->getPositionInformation();
528 GUIGLObjectPopupMenu* ret = new GUIGLObjectPopupMenu(app, parent, this);
529 buildPopupHeader(ret, app);
531 // build copy names entry
532 if (editMode != NetworkEditMode::NETWORK_TLS) {
533 GUIDesigns::buildFXMenuCommand(ret, TL("Copy parent edge name to clipboard"), nullptr, ret, MID_COPY_EDGE_NAME);
535 }
536 // stop if we're in data mode
538 return ret;
539 }
540 // build lane selection
543 } else {
545 }
546 // build edge selection
549 } else {
551 }
552 // stop if we're in data mode
554 return ret;
555 }
556 // add separator
557 new FXMenuSeparator(ret);
558 if (editMode != NetworkEditMode::NETWORK_TLS) {
559 // build show parameters menu
561 // build position copy entry
562 buildPositionCopyEntry(ret, app);
563 }
564 // check if we're in supermode network
566 // create end point
567 FXMenuCommand* resetEndPoints = GUIDesigns::buildFXMenuCommand(ret, TL("Reset edge end points"), nullptr, &parent, MID_GNE_RESET_GEOMETRYPOINT);
568 // enable or disable reset end points
569 if (getParentEdges().front()->hasCustomEndPoints()) {
570 resetEndPoints->enable();
571 } else {
572 resetEndPoints->disable();
573 }
574 // check if we clicked over a geometry point
575 if ((editMode == NetworkEditMode::NETWORK_MOVE) && getParentEdges().front()->clickedOverGeometryPoint(mousePosition)) {
576 GUIDesigns::buildFXMenuCommand(ret, TL("Set custom Geometry Point"), nullptr, &parent, MID_GNE_CUSTOM_GEOMETRYPOINT);
577 }
578 // add separator
579 new FXMenuSeparator(ret);
580 //build operations
581 if ((editMode != NetworkEditMode::NETWORK_CONNECT) && (editMode != NetworkEditMode::NETWORK_TLS)) {
582 // build edge operations
583 buildEdgeOperations(parent, ret);
584 // build lane operations
585 buildLaneOperations(parent, ret);
586 // build template operations
587 buildTemplateOperations(parent, ret);
588 // add separator
589 new FXMenuSeparator(ret);
590 // build rechable operations
591 buildRechableOperations(parent, ret);
592 } else if (editMode == NetworkEditMode::NETWORK_TLS) {
594 GUIDesigns::buildFXMenuCommand(ret, TL("Select state for all links from this edge:"), nullptr, nullptr, 0);
595 const std::vector<std::string> names = GNEInternalLane::LinkStateNames.getStrings();
596 for (auto it : names) {
597 FXuint state = GNEInternalLane::LinkStateNames.get(it);
598 FXMenuRadio* mc = new FXMenuRadio(ret, it.c_str(), this, FXDataTarget::ID_OPTION + state);
601 }
602 }
603 } else {
604 FXMenuCommand* mc = GUIDesigns::buildFXMenuCommand(ret, TL("Additional options available in 'Inspect Mode'"), nullptr, nullptr, 0);
605 mc->handle(&parent, FXSEL(SEL_COMMAND, FXWindow::ID_DISABLE), nullptr);
606 }
607 // build shape positions menu
608 if (editMode != NetworkEditMode::NETWORK_TLS) {
609 new FXMenuSeparator(ret);
610 // get lane shape
611 const auto& laneShape = myLaneGeometry.getShape();
612 // get variables
613 const double pos = laneShape.nearest_offset_to_point2D(mousePosition);
614 const Position firstAnglePos = laneShape.positionAtOffset2D(pos - 0.001);
615 const Position secondAnglePos = laneShape.positionAtOffset2D(pos);
616 const double angle = firstAnglePos.angleTo2D(secondAnglePos);
617
618 // build menu commands
619 GUIDesigns::buildFXMenuCommand(ret, TL("Shape pos: ") + toString(pos), nullptr, nullptr, 0);
620 GUIDesigns::buildFXMenuCommand(ret, TL("Length pos: ") + toString(pos * getLaneParametricLength() / getLaneShapeLength()), nullptr, nullptr, 0);
621 if (getParentEdges().front()->getNBEdge()->getDistance() != 0) {
622 GUIDesigns::buildFXMenuCommand(ret, TL("Distance: ") + toString(getParentEdges().front()->getNBEdge()->getDistancAt(pos)), nullptr, nullptr, 0);
623 }
624 GUIDesigns::buildFXMenuCommand(ret, TL("Height: ") + toString(firstAnglePos.z()), nullptr, nullptr, 0);
625 GUIDesigns::buildFXMenuCommand(ret, TL("Angle: ") + toString((GeomHelper::naviDegree(angle))), nullptr, nullptr, 0);
626 }
627 }
628 return ret;
629}
630
631
632double
634 return s.addSize.getExaggeration(s, this);
635}
636
637
642
643
644void
645GNELane::updateCenteringBoundary(const bool /*updateGrid*/) {
646 // nothing to update
647}
648
649
650int
652 return myIndex;
653}
654
655
656void
658 myIndex = index;
659 setNetworkElementID(getParentEdges().front()->getNBEdge()->getLaneID(index));
660}
661
662
663double
665 return getParentEdges().front()->getNBEdge()->getLaneSpeed(myIndex);
666}
667
668
669double
671 double laneParametricLength = getParentEdges().front()->getNBEdge()->getLoadedLength();
672 if (laneParametricLength > 0) {
673 return laneParametricLength;
674 } else {
675 throw ProcessError(TL("Lane Parametric Length cannot be never 0"));
676 }
677}
678
679
680double
684
685
686bool
688 return getParentEdges().front()->getNBEdge()->getPermissions(myIndex) == vclass;
689}
690
691
696
697
698std::string
700 const NBEdge* edge = getParentEdges().front()->getNBEdge();
701 switch (key) {
702 case SUMO_ATTR_ID:
703 return getMicrosimID();
705 return getParentEdges().front()->getFromJunction()->getID();
707 return getParentEdges().front()->getToJunction()->getID();
708 case SUMO_ATTR_SPEED:
709 return toString(edge->getLaneSpeed(myIndex));
710 case SUMO_ATTR_ALLOW:
718 case SUMO_ATTR_WIDTH:
720 return "default";
721 } else {
722 return toString(edge->getLaneStruct(myIndex).width);
723 }
725 return toString(edge->getLaneStruct(myIndex).friction);
730 case SUMO_ATTR_SHAPE:
735 case SUMO_ATTR_TYPE:
736 return edge->getLaneStruct(myIndex).type;
737 case SUMO_ATTR_INDEX:
738 return toString(myIndex);
744 } else {
745 return "";
746 }
747 case GNE_ATTR_PARENT:
748 return getParentEdges().front()->getID();
749 default:
750 return getCommonAttribute(&edge->getLaneStruct(myIndex), key);
751 }
752}
753
754
757 switch (key) {
758 case SUMO_ATTR_SHAPE:
760 return getParentEdges().front()->getNBEdge()->getLaneStruct(myIndex).customShape;
761 default:
762 throw InvalidArgument(getTagStr() + " doesn't have an attribute of type '" + toString(key) + "'");
763 }
764}
765
766
767std::string
769 std::string result = getAttribute(key);
770 if ((key == SUMO_ATTR_ALLOW || key == SUMO_ATTR_DISALLOW) && result.find("all") != std::string::npos) {
771 result += " " + getVehicleClassNames(SVCAll, true);
772 }
773 return result;
774}
775
776
777void
778GNELane::setAttribute(SumoXMLAttr key, const std::string& value, GNEUndoList* undoList) {
779 switch (key) {
780 case SUMO_ATTR_ID:
781 throw InvalidArgument("Modifying attribute '" + toString(key) + "' of " + getTagStr() + " isn't allowed");
782 case SUMO_ATTR_SPEED:
783 case SUMO_ATTR_ALLOW:
787 case SUMO_ATTR_WIDTH:
791 case SUMO_ATTR_SHAPE:
794 case SUMO_ATTR_TYPE:
795 case SUMO_ATTR_INDEX:
797 // special case for stop offset, because affects to stopOffsetExceptions (#15297)
798 if (canParse<double>(value) && (parse<double>(value) == 0)) {
800 }
801 GNEChange_Attribute::changeAttribute(this, key, value, undoList);
802 break;
804 GNEChange_Attribute::changeAttribute(this, key, value, undoList);
805 break;
806 default:
807 setCommonAttribute(key, value, undoList);
808 break;
809 }
810}
811
812
813bool
814GNELane::isValid(SumoXMLAttr key, const std::string& value) {
815 switch (key) {
816 case SUMO_ATTR_ID:
817 case SUMO_ATTR_INDEX:
818 return false;
819 case SUMO_ATTR_SPEED:
820 return canParse<double>(value);
821 case SUMO_ATTR_ALLOW:
825 return canParseVehicleClasses(value);
826 case SUMO_ATTR_WIDTH:
827 if (value.empty() || (value == "default")) {
828 return true;
829 } else {
830 return canParse<double>(value) && ((parse<double>(value) > 0) || (parse<double>(value) == NBEdge::UNSPECIFIED_WIDTH));
831 }
834 return canParse<double>(value) && (parse<double>(value) >= 0);
836 return canParse<bool>(value);
837 case SUMO_ATTR_SHAPE:
839 // A lane shape can either be empty or have more than 1 element
840 if (value.empty()) {
841 return true;
842 } else if (canParse<PositionVector>(value)) {
843 return parse<PositionVector>(value).size() > 1;
844 }
845 return false;
846 case GNE_ATTR_OPPOSITE: {
847 if (value.empty()) {
848 return true;
849 } else {
850 NBEdge* oppEdge = myNet->getEdgeCont().retrieve(value.substr(0, value.rfind("_")));
851 if (oppEdge == nullptr || oppEdge->getLaneID(oppEdge->getNumLanes() - 1) != value) {
852 return false;
853 }
854 NBEdge* edge = getParentEdges().front()->getNBEdge();
855 if (oppEdge->getFromNode() != edge->getToNode() || oppEdge->getToNode() != edge->getFromNode()) {
856 WRITE_WARNINGF(TL("Opposite lane '%' does not connect the same nodes as edge '%'!"), value, edge->getID());
857 return false;
858 }
859 return true;
860 }
861 }
862 case SUMO_ATTR_TYPE:
863 return true;
865 return canParse<double>(value) && (parse<double>(value) >= 0);
867 return canParseVehicleClasses(value);
868 default:
869 return isCommonValid(key, value);
870 }
871}
872
873
874bool
876 switch (key) {
877 case SUMO_ATTR_ID:
878 case SUMO_ATTR_INDEX:
879 return false;
881 return getParentEdges().front()->getNBEdge()->getLaneStruct(myIndex).laneStopOffset.getOffset() > 0;
882 default:
883 return true;
884 }
885}
886
887
888bool
890 const NBEdge* edge = getParentEdges().front()->getNBEdge();
891 switch (key) {
892 case SUMO_ATTR_WIDTH:
894 default:
895 return false;
896 }
897}
898
899
902 return getParentEdges().front()->getNBEdge()->getLaneStruct(myIndex).getParametersMap();
903}
904
905
906void
907GNELane::setSpecialColor(const RGBColor* color, double colorValue) {
908 mySpecialColor = color;
909 mySpecialColorValue = colorValue;
910}
911
912// ===========================================================================
913// private
914// ===========================================================================
915
916void
917GNELane::setAttribute(SumoXMLAttr key, const std::string& value) {
918 // get parent edge
919 NBEdge* edge = getParentEdges().front()->getNBEdge();
920 // get template editor
922 // check if we have to update template
923 const bool updateTemplate = templateEditor->getEdgeTemplate() ? (templateEditor->getEdgeTemplate()->getID() == getParentEdges().front()->getID()) : false;
924 switch (key) {
925 case SUMO_ATTR_ID:
926 case SUMO_ATTR_INDEX:
927 throw InvalidArgument("Modifying attribute '" + toString(key) + "' of " + getTagStr() + " isn't allowed");
928 case SUMO_ATTR_SPEED:
929 edge->setSpeed(myIndex, parse<double>(value));
930 break;
931 case SUMO_ATTR_ALLOW:
933 break;
936 break;
939 break;
942 break;
943 case SUMO_ATTR_WIDTH:
944 if (value.empty() || (value == "default")) {
946 } else {
947 edge->setLaneWidth(myIndex, parse<double>(value));
948 }
949 // update edge parent boundary
950 getParentEdges().front()->updateCenteringBoundary(true);
951 break;
953 edge->setFriction(myIndex, parse<double>(value));
954 break;
956 edge->setEndOffset(myIndex, parse<double>(value));
957 break;
959 edge->setAcceleration(myIndex, parse<bool>(value));
960 break;
961 case SUMO_ATTR_SHAPE:
963 // set new shape
964 edge->setLaneShape(myIndex, parse<PositionVector>(value));
965 // update edge parent boundary
966 getParentEdges().front()->updateCenteringBoundary(true);
967 break;
968 case GNE_ATTR_OPPOSITE: {
969 if (value != "") {
970 NBEdge* oppEdge = myNet->getEdgeCont().retrieve(value.substr(0, value.rfind("_")));
971 oppEdge->getLaneStruct(oppEdge->getNumLanes() - 1).oppositeID = getID();
972 } else {
973 // reset prior oppEdge if existing
974 const std::string oldValue = getParentEdges().front()->getNBEdge()->getLaneStruct(myIndex).oppositeID;
975 NBEdge* oppEdge = myNet->getEdgeCont().retrieve(oldValue.substr(0, oldValue.rfind("_")));
976 if (oppEdge != nullptr) {
977 oppEdge->getLaneStruct(oppEdge->getNumLanes() - 1).oppositeID = "";
978 }
979 }
980 getParentEdges().front()->getNBEdge()->getLaneStruct(myIndex).oppositeID = value;
981 break;
982 }
983 case SUMO_ATTR_TYPE:
984 edge->getLaneStruct(myIndex).type = value;
985 break;
987 if (value.empty()) {
989 } else {
990 edge->getLaneStruct(myIndex).laneStopOffset.setOffset(parse<double>(value));
991 }
992 break;
995 break;
996 default:
997 setCommonAttribute(&edge->getLaneStruct(myIndex), key, value);
998 break;
999 }
1000 // update template
1001 if (updateTemplate) {
1002 templateEditor->setEdgeTemplate(getParentEdges().front());
1003 }
1004 // invalidate demand path calculator
1006}
1007
1008
1009void
1011 // set custom shape
1012 getParentEdges().front()->getNBEdge()->getLaneStruct(myIndex).customShape = moveResult.shapeToUpdate;
1013 // update geometry
1015}
1016
1017
1018void
1020 // commit new shape
1021 undoList->begin(this, "moving " + toString(SUMO_ATTR_CUSTOMSHAPE) + " of " + getTagStr());
1023 undoList->end();
1024}
1025
1026
1027void
1028GNELane::drawLane(const GUIVisualizationSettings& s, const double layer) const {
1029 // Push layer matrix
1031 // translate to layer
1032 drawInLayer(layer);
1033 // set lane colors
1034 setLaneColor(s);
1035 // Check if lane has to be draw as railway and if isn't being drawn for selecting
1037 // draw as railway
1039 } else if (myShapeColors.size() > 0) {
1040 // draw geometry with own colors
1043 } else {
1044 // draw geometry with current color
1046 double drawingWidth = myDrawingConstants->getDrawingWidth();
1048 drawingWidth = myNet->getViewNet()->m2p(drawingWidth);
1049 }
1052 }
1053 // if lane is selected, draw a second lane over it
1055 // draw start end shape points
1057 // check if draw details
1059 // draw markings
1061 // Draw direction indicators
1063 // draw lane textures
1064 drawTextures(s);
1065 // draw lane arrows
1066 drawArrows(s);
1067 // draw link numbers
1068 drawLinkNo(s);
1069 // draw TLS link numbers
1070 drawTLSLinkNo(s);
1071 // draw stopOffsets
1073 }
1074 // draw shape edited
1075 drawShapeEdited(s);
1076 // Pop layer matrix
1078}
1079
1080
1081void
1083 // only draw if lane is selected
1084 if (drawUsingSelectColor()) {
1085 // Push matrix
1087 // move back
1088 glTranslated(0, 0, 0.1);
1089 // set selected edge color
1091 // draw geometry with current color
1094 // Pop matrix
1096 }
1097}
1098
1099
1100void
1102 // if shape is being edited, draw point and green line
1103 if (myShapeEdited) {
1104 // push shape edited matrix
1106 // translate
1108 // set selected edge color
1110 // draw shape around
1113 // move front
1114 glTranslated(0, 0, 1);
1115 // draw geometry points
1120 // Pop shape edited matrix
1122 }
1123}
1124
1125
1126void
1128 // draw additional children
1129 for (const auto& additional : getChildAdditionals()) {
1130 if (!additional->getTagProperty()->isListedElement()) {
1131 additional->drawGL(s);
1132 }
1133 }
1134 // draw demand element children
1135 for (const auto& demandElement : getChildDemandElements()) {
1136 if (!demandElement->getTagProperty()->isPlacedInRTree()) {
1137 demandElement->drawGL(s);
1138 }
1139 }
1140 // draw path additional elements
1144}
1145
1146
1147void
1149 // check conditions
1151 // check if this is the last lane (note: First lane is the lane more far of the edge's center)
1152 const bool firstlane = (myIndex == 0);
1153 const bool lastLane = (myIndex == (getParentEdges().front()->getNBEdge()->getNumLanes() - 1));
1154 // declare separator width
1155 const auto separatorWidth = SUMO_const_laneMarkWidth * 0.5;
1156 // get passengers change left and right for previous, current and next lane
1157 const bool changeRightTop = lastLane ? true : getParentEdges().front()->getNBEdge()->allowsChangingRight(myIndex + 1, SVC_PASSENGER);
1158 const bool changeLeftCurrent = lastLane ? true : getParentEdges().front()->getNBEdge()->allowsChangingLeft(myIndex, SVC_PASSENGER);
1159 const bool changeRightCurrent = firstlane ? true : getParentEdges().front()->getNBEdge()->allowsChangingRight(myIndex, SVC_PASSENGER);
1160 const bool changeLeftBot = firstlane ? true : getParentEdges().front()->getNBEdge()->allowsChangingLeft(myIndex - 1, SVC_PASSENGER);
1161 // save current color
1162 const auto currentColor = GLHelper::getColor();
1163 // separator offsets
1164 const double topSeparatorOffset = myDrawingConstants->getOffset() + (myDrawingConstants->getDrawingWidth() * -1) + separatorWidth;
1165 const double botSeparatorOffset = myDrawingConstants->getOffset() + myDrawingConstants->getDrawingWidth() - separatorWidth;
1166 // push matrix
1168 // translate
1169 glTranslated(0, 0, 0.1);
1170 // continue depending of lanes
1171 if (myDrawingConstants->drawSuperposed() || (firstlane && lastLane)) {
1172 // draw top and bot separator only
1174 GUIGeometry::drawGeometry(myDrawingConstants->getDetail(), myLaneGeometry, separatorWidth, topSeparatorOffset);
1175 GUIGeometry::drawGeometry(myDrawingConstants->getDetail(), myLaneGeometry, separatorWidth, botSeparatorOffset);
1176 } else if (firstlane) {
1177 // draw top separator
1178 GLHelper::setColor((changeLeftCurrent && changeRightTop) ? RGBColor::WHITE : RGBColor::ORANGE);
1179 GUIGeometry::drawGeometry(myDrawingConstants->getDetail(), myLaneGeometry, separatorWidth, topSeparatorOffset);
1180 // check if draw inverse marking
1181 if (changeLeftCurrent) {
1182 GLHelper::setColor(currentColor);
1184 3, 6, topSeparatorOffset, true, true, s.lefthand, 1);
1185 }
1186 // draw bot separator
1188 GUIGeometry::drawGeometry(myDrawingConstants->getDetail(), myLaneGeometry, separatorWidth, botSeparatorOffset);
1189 } else if (lastLane) {
1190 // draw top separator
1192 GUIGeometry::drawGeometry(myDrawingConstants->getDetail(), myLaneGeometry, separatorWidth, topSeparatorOffset);
1193 // draw bot separator
1194 GLHelper::setColor((changeRightCurrent && changeLeftBot) ? RGBColor::WHITE : RGBColor::ORANGE);
1195 GUIGeometry::drawGeometry(myDrawingConstants->getDetail(), myLaneGeometry, separatorWidth, botSeparatorOffset);
1196 // check if draw inverse marking
1197 if (changeRightCurrent) {
1198 GLHelper::setColor(currentColor);
1200 3, 6, botSeparatorOffset, true, true, s.lefthand, 1);
1201 }
1202 } else {
1203 // draw top separator
1204 GLHelper::setColor((changeLeftCurrent && changeRightTop) ? RGBColor::WHITE : RGBColor::ORANGE);
1205 GUIGeometry::drawGeometry(myDrawingConstants->getDetail(), myLaneGeometry, separatorWidth, topSeparatorOffset);
1206 // check if draw inverse marking
1207 if (changeLeftCurrent) {
1208 GLHelper::setColor(currentColor);
1210 3, 6, topSeparatorOffset, true, true, s.lefthand, 1);
1211 }
1212 // draw bot separator
1213 GLHelper::setColor((changeRightCurrent && changeLeftBot) ? RGBColor::WHITE : RGBColor::ORANGE);
1214 GUIGeometry::drawGeometry(myDrawingConstants->getDetail(), myLaneGeometry, separatorWidth, botSeparatorOffset);
1215 // check if draw inverse marking
1216 if (changeRightCurrent) {
1217 GLHelper::setColor(currentColor);
1219 3, 6, botSeparatorOffset, true, true, s.lefthand, 1);
1220 }
1221 }
1222 // pop matrix
1224 }
1225}
1226
1227
1228void
1230 // check draw conditions
1231 if (s.drawLinkJunctionIndex.show(getParentEdges().front()->getToJunction())) {
1232 // get connections
1233 const auto& connections = getParentEdges().front()->getNBEdge()->getConnectionsFromLane(myIndex);
1234 // get number of links
1235 const int noLinks = (int)connections.size();
1236 // only continue if there is links
1237 if (noLinks > 0) {
1238 // push link matrix
1240 // move front
1241 glTranslated(0, 0, GLO_TEXTNAME);
1242 // calculate width
1243 const double width = getParentEdges().front()->getNBEdge()->getLaneWidth(myIndex) / (double) noLinks;
1244 // get X1
1245 double x1 = getParentEdges().front()->getNBEdge()->getLaneWidth(myIndex) / 2;
1246 // iterate over links
1247 for (int i = noLinks - 1; i >= 0; i--) {
1248 // calculate x2
1249 const double x2 = x1 - (double)(width / 2.);
1250 // get link index
1251 const int linkIndex = getParentEdges().front()->getNBEdge()->getToNode()->getConnectionIndex(getParentEdges().front()->getNBEdge(),
1252 connections[s.lefthand ? noLinks - 1 - i : i]);
1253 // draw link index
1255 // update x1
1256 x1 -= width;
1257 }
1258 // pop link matrix
1260 }
1261 }
1262}
1263
1264
1265void
1267 // check conditions
1269 (getParentEdges().front()->getToJunction()->getNBNode()->getControllingTLS().size() > 0)) {
1270 // get connections
1271 const auto& connections = getParentEdges().front()->getNBEdge()->getConnectionsFromLane(myIndex);
1272 // get numer of links
1273 const int noLinks = (int)connections.size();
1274 // only continue if there are links
1275 if (noLinks > 0) {
1276 // push link matrix
1278 // move t front
1279 glTranslated(0, 0, GLO_TEXTNAME);
1280 // calculate width
1281 const double w = getParentEdges().front()->getNBEdge()->getLaneWidth(myIndex) / (double) noLinks;
1282 // calculate x1
1283 double x1 = getParentEdges().front()->getNBEdge()->getLaneWidth(myIndex) / 2;
1284 // iterate over links
1285 for (int i = noLinks - 1; i >= 0; --i) {
1286 // calculate x2
1287 const double x2 = x1 - (double)(w / 2.);
1288 // get link number
1289 const int linkNo = connections[s.lefthand ? noLinks - 1 - i : i].tlLinkIndex;
1290 // draw link number
1292 // update x1
1293 x1 -= w;
1294 }
1295 // pop link matrix
1297 }
1298 }
1299}
1300
1301
1302void
1304 if (s.showLinkDecals && getParentEdges().front()->getToJunction()->isLogicValid()) {
1305 // calculate begin, end and rotation
1306 const Position& begin = myLaneGeometry.getShape()[-2];
1307 const Position& end = myLaneGeometry.getShape().back();
1308 const double rot = GUIGeometry::calculateRotation(begin, end);
1309 // push arrow matrix
1311 // move front (note: must draw on top of junction shape?
1312 glTranslated(0, 0, 3);
1313 // change color depending of spreadSuperposed
1316 } else {
1318 }
1319 // move to end
1320 glTranslated(end.x(), end.y(), 0);
1321 // rotate
1322 glRotated(rot, 0, 0, 1);
1323 const double width = getParentEdges().front()->getNBEdge()->getLaneWidth(myIndex);
1324 if (width < SUMO_const_laneWidth) {
1326 }
1327 // apply offset
1328 glTranslated(myDrawingConstants->getOffset() * -1, 0, 0);
1329 // get destination node
1330 const NBNode* dest = getParentEdges().front()->getNBEdge()->myTo;
1331 // draw all links iterating over connections
1332 for (const auto& connection : getParentEdges().front()->getNBEdge()->myConnections) {
1333 if (connection.fromLane == myIndex) {
1334 // get link direction
1335 LinkDirection dir = dest->getDirection(getParentEdges().front()->getNBEdge(), connection.toEdge, s.lefthand);
1336 // draw depending of link direction
1337 switch (dir) {
1339 GLHelper::drawBoxLine(Position(0, 4), 0, 2, .05);
1340 GLHelper::drawTriangleAtEnd(Position(0, 4), Position(0, 1), (double) 1, (double) .25);
1341 break;
1343 GLHelper::drawBoxLine(Position(0, 4), 0, 1.5, .05);
1344 GLHelper::drawBoxLine(Position(0, 2.5), 90, 1, .05);
1345 GLHelper::drawTriangleAtEnd(Position(0, 2.5), Position(1.5, 2.5), (double) 1, (double) .25);
1346 break;
1348 GLHelper::drawBoxLine(Position(0, 4), 0, 1.5, .05);
1349 GLHelper::drawBoxLine(Position(0, 2.5), -90, 1, .05);
1350 GLHelper::drawTriangleAtEnd(Position(0, 2.5), Position(-1.5, 2.5), (double) 1, (double) .25);
1351 break;
1353 GLHelper::drawBoxLine(Position(0, 4), 0, 1.5, .05);
1354 GLHelper::drawBoxLine(Position(0, 2.5), 90, .5, .05);
1355 GLHelper::drawBoxLine(Position(0.5, 2.5), 180, 1, .05);
1356 GLHelper::drawTriangleAtEnd(Position(0.5, 2.5), Position(0.5, 4), (double) 1, (double) .25);
1357 break;
1359 GLHelper::drawBoxLine(Position(0, 4), 0, 1.5, .05);
1360 GLHelper::drawBoxLine(Position(0, 2.5), -90, 1, .05);
1361 GLHelper::drawBoxLine(Position(-0.5, 2.5), -180, 1, .05);
1362 GLHelper::drawTriangleAtEnd(Position(-0.5, 2.5), Position(-0.5, 4), (double) 1, (double) .25);
1363 break;
1365 GLHelper::drawBoxLine(Position(0, 4), 0, 1.5, .05);
1366 GLHelper::drawBoxLine(Position(0, 2.5), 45, .7, .05);
1367 GLHelper::drawTriangleAtEnd(Position(0, 2.5), Position(1.2, 1.3), (double) 1, (double) .25);
1368 break;
1370 GLHelper::drawBoxLine(Position(0, 4), 0, 1.5, .05);
1371 GLHelper::drawBoxLine(Position(0, 2.5), -45, .7, .05);
1372 GLHelper::drawTriangleAtEnd(Position(0, 2.5), Position(-1.2, 1.3), (double) 1, (double) .25);
1373 break;
1375 GLHelper::drawBoxLine(Position(1, 5.8), 245, 2, .05);
1376 GLHelper::drawBoxLine(Position(-1, 5.8), 115, 2, .05);
1377 glTranslated(0, 5, 0);
1378 GLHelper::drawOutlineCircle(0.9, 0.8, 32);
1379 glTranslated(0, -5, 0);
1380 break;
1381 }
1382 }
1383 }
1384 // pop arrow matrix
1386 }
1387}
1388
1389
1390void
1393 glTranslated(0, 0, 0.1); // must draw on top of junction shape
1394 std::vector<NBEdge::Connection> connections = getParentEdges().front()->getNBEdge()->getConnectionsFromLane(myIndex);
1395 NBNode* node = getParentEdges().front()->getNBEdge()->getToNode();
1396 const Position& startPos = myLaneGeometry.getShape()[-1];
1397 for (auto it : connections) {
1398 const LinkState state = node->getLinkState(getParentEdges().front()->getNBEdge(), it.toEdge, it.fromLane, it.toLane, it.mayDefinitelyPass, it.tlID);
1399 switch (state) {
1401 glColor3d(1, 1, 0);
1402 break;
1404 glColor3d(0, 1, 1);
1405 break;
1406 case LINKSTATE_MAJOR:
1407 glColor3d(1, 1, 1);
1408 break;
1409 case LINKSTATE_MINOR:
1410 glColor3d(.4, .4, .4);
1411 break;
1412 case LINKSTATE_STOP:
1413 glColor3d(.7, .4, .4);
1414 break;
1415 case LINKSTATE_EQUAL:
1416 glColor3d(.7, .7, .7);
1417 break;
1419 glColor3d(.7, .7, 1);
1420 break;
1421 case LINKSTATE_ZIPPER:
1422 glColor3d(.75, .5, 0.25);
1423 break;
1424 default:
1425 throw ProcessError(TLF("Unexpected LinkState '%'", toString(state)));
1426 }
1427 const Position& endPos = it.toEdge->getLaneShape(it.toLane)[0];
1428 glBegin(GL_LINES);
1429 glVertex2d(startPos.x(), startPos.y());
1430 glVertex2d(endPos.x(), endPos.y());
1431 glEnd();
1432 GLHelper::drawTriangleAtEnd(startPos, endPos, (double) 1.5, (double) .2);
1433 }
1435}
1436
1437
1438void
1439GNELane::calculateLaneContour(const GUIVisualizationSettings& s, const double layer) const {
1440 // first check if edge parent was inserted with full boundary
1441 if (!gViewObjectsHandler.checkBoundaryParentObject(this, layer, getParentEdges().front())) {
1442 // calculate contour
1445 true, true, myDrawingConstants->getOffset(), nullptr, getParentEdges().front());
1446 // calculate geometry points contour if we're editing shape
1447 if (myShapeEdited) {
1451 }
1452 }
1453}
1454
1455
1458 const auto& inspectedElements = myNet->getViewNet()->getInspectedElements();
1459 // declare a RGBColor variable
1460 RGBColor color;
1461 // we need to draw lanes with a special color if we're inspecting a Trip or Flow and this lane belongs to a via's edge.
1462 if (inspectedElements.getFirstAC() &&
1463 !inspectedElements.getFirstAC()->isAttributeCarrierSelected() &&
1464 inspectedElements.getFirstAC()->getTagProperty()->vehicleEdges()) {
1465 // obtain attribute "via"
1466 std::vector<std::string> viaEdges = parse<std::vector<std::string> >(inspectedElements.getFirstAC()->getAttribute(SUMO_ATTR_VIA));
1467 // iterate over viaEdges
1468 for (const auto& edge : viaEdges) {
1469 // check if parent edge is in the via edges
1470 if (getParentEdges().front()->getID() == edge) {
1471 // set green color in GLHelper and return it
1472 color = RGBColor::GREEN;
1473 }
1474 }
1475 }
1476 if (mySpecialColor != nullptr) {
1477 // If special color is enabled, set it
1478 color = *mySpecialColor;
1479 } else if (getParentEdges().front()->drawUsingSelectColor() && s.laneColorer.getActive() != 1) {
1480 // override with special colors (unless the color scheme is based on selection)
1482 } else {
1483 // Get normal lane color
1484 const GUIColorer& c = s.laneColorer;
1485 if (!setFunctionalColor(c.getActive(), color) && !setMultiColor(s, c, color)) {
1486 color = c.getScheme().getColor(getColorValue(s, c.getActive()));
1487 }
1488 }
1489 // special color for conflicted candidate edges
1490 if (getParentEdges().front()->isConflictedCandidate()) {
1491 // extra check for route frame
1494 }
1495 }
1496 // special color for special candidate edges
1497 if (getParentEdges().front()->isSpecialCandidate()) {
1498 // extra check for route frame
1501 }
1502 }
1503 // special color for candidate edges
1504 if (getParentEdges().front()->isPossibleCandidate()) {
1505 // extra check for route frame
1508 }
1509 }
1510 // special color for source candidate edges
1511 if (getParentEdges().front()->isSourceCandidate()) {
1513 }
1514 // special color for target candidate edges
1515 if (getParentEdges().front()->isTargetCandidate()) {
1517 }
1518 // special color for invalid candidate edges
1519 if (getParentEdges().front()->isInvalidCandidate()) {
1521 }
1522 // special color for source candidate lanes
1523 if (mySourceCandidate) {
1525 }
1526 // special color for target candidate lanes
1527 if (myTargetCandidate) {
1529 }
1530 // special color for special candidate lanes
1531 if (mySpecialCandidate) {
1533 }
1534 // special color for possible candidate lanes
1535 if (myPossibleCandidate) {
1537 }
1538 // special color for conflicted candidate lanes
1541 }
1542 // special color for invalid candidate lanes
1543 if (myInvalidCandidate) {
1545 }
1546 // set color in GLHelper
1547 GLHelper::setColor(color);
1548 return color;
1549}
1550
1551
1552bool
1553GNELane::setFunctionalColor(int activeScheme, RGBColor& col) const {
1554 switch (activeScheme) {
1555 case 6: {
1556 double hue = GeomHelper::naviDegree(myLaneGeometry.getShape().beginEndAngle()); // [0-360]
1557 col = RGBColor::fromHSV(hue, 1., 1.);
1558 return true;
1559 }
1560 default:
1561 return false;
1562 }
1563}
1564
1565
1566bool
1568 const int activeScheme = c.getActive();
1569 myShapeColors.clear();
1570 switch (activeScheme) {
1571 case 9: // color by height at segment start
1572 for (PositionVector::const_iterator ii = myLaneGeometry.getShape().begin(); ii != myLaneGeometry.getShape().end() - 1; ++ii) {
1573 myShapeColors.push_back(c.getScheme().getColor(ii->z()));
1574 }
1575 col = c.getScheme().getColor(getColorValue(s, 8));
1576 return true;
1577 case 11: // color by inclination at segment start
1578 for (int ii = 1; ii < (int)myLaneGeometry.getShape().size(); ++ii) {
1579 const double inc = (myLaneGeometry.getShape()[ii].z() - myLaneGeometry.getShape()[ii - 1].z()) / MAX2(POSITION_EPS, myLaneGeometry.getShape()[ii].distanceTo2D(myLaneGeometry.getShape()[ii - 1]));
1580 myShapeColors.push_back(c.getScheme().getColor(inc));
1581 }
1582 col = c.getScheme().getColor(getColorValue(s, 10));
1583 return true;
1584 default:
1585 return false;
1586 }
1587}
1588
1589
1590double
1591GNELane::getColorValue(const GUIVisualizationSettings& s, int activeScheme) const {
1592 const SVCPermissions myPermissions = getParentEdges().front()->getNBEdge()->getPermissions(myIndex);
1593 if (mySpecialColor != nullptr && mySpecialColorValue != std::numeric_limits<double>::max()) {
1594 return mySpecialColorValue;
1595 }
1596 switch (activeScheme) {
1597 case 0:
1598 switch (myPermissions) {
1599 case SVC_PEDESTRIAN:
1600 return 1;
1601 case SVC_BICYCLE:
1602 return 2;
1603 case 0:
1604 // forbidden road or green verge
1605 return getParentEdges().front()->getNBEdge()->getPermissions() == 0 ? 10 : 3;
1606 case SVC_SHIP:
1607 return 4;
1608 case SVC_AUTHORITY:
1609 return 8;
1610 case SVC_AIRCRAFT:
1611 case SVC_DRONE:
1612 return 12;
1613 default:
1614 break;
1615 }
1616 if (getParentEdges().front()->getNBEdge()->isMacroscopicConnector()) {
1617 return 9;
1618 } else if (isRailway(myPermissions)) {
1619 return 5;
1620 } else if ((myPermissions & SVC_PASSENGER) != 0) {
1621 if ((myPermissions & (SVC_RAIL_CLASSES & ~SVC_RAIL_FAST)) != 0 && (myPermissions & SVC_SHIP) == 0) {
1622 return 6;
1623 } else {
1624 return 0;
1625 }
1626 } else {
1627 if ((myPermissions & SVC_RAIL_CLASSES) != 0 && (myPermissions & SVC_SHIP) == 0) {
1628 return 6;
1629 } else {
1630 return 7;
1631 }
1632 }
1633 case 1:
1634 return isAttributeCarrierSelected() || getParentEdges().front()->isAttributeCarrierSelected();
1635 case 2:
1636 return (double)myPermissions;
1637 case 3:
1638 return getParentEdges().front()->getNBEdge()->getLaneSpeed(myIndex);
1639 case 4:
1640 return getParentEdges().front()->getNBEdge()->getNumLanes();
1641 case 5: {
1642 return getParentEdges().front()->getNBEdge()->getLoadedLength() / getParentEdges().front()->getNBEdge()->getLaneStruct(myIndex).shape.length();
1643 }
1644 // case 6: by angle (functional)
1645 case 7: {
1646 return getParentEdges().front()->getNBEdge()->getPriority();
1647 }
1648 case 8: {
1649 // color by z of first shape point
1650 return myLaneGeometry.getShape()[0].z();
1651 }
1652 // case 9: by segment height
1653 case 10: {
1654 // color by incline
1655 return (myLaneGeometry.getShape()[-1].z() - myLaneGeometry.getShape()[0].z()) / getParentEdges().front()->getNBEdge()->getLength();
1656 }
1657 // case 11: by segment incline
1658
1659 case 12: {
1660 // by numerical edge param value
1661 if (getParentEdges().front()->getNBEdge()->hasParameter(s.edgeParam)) {
1662 try {
1663 return StringUtils::toDouble(getParentEdges().front()->getNBEdge()->getParameter(s.edgeParam, "0"));
1664 } catch (NumberFormatException&) {
1665 try {
1666 return StringUtils::toBool(getParentEdges().front()->getNBEdge()->getParameter(s.edgeParam, "0"));
1667 } catch (BoolFormatException&) {
1668 return -1;
1669 }
1670 }
1671 } else {
1673 }
1674 }
1675 case 13: {
1676 // by numerical lane param value
1677 if (getParentEdges().front()->getNBEdge()->getLaneStruct(myIndex).hasParameter(s.laneParam)) {
1678 try {
1679 return StringUtils::toDouble(getParentEdges().front()->getNBEdge()->getLaneStruct(myIndex).getParameter(s.laneParam, "0"));
1680 } catch (NumberFormatException&) {
1681 try {
1682 return StringUtils::toBool(getParentEdges().front()->getNBEdge()->getLaneStruct(myIndex).getParameter(s.laneParam, "0"));
1683 } catch (BoolFormatException&) {
1684 return -1;
1685 }
1686 }
1687 } else {
1689 }
1690 }
1691 case 14: {
1692 return getParentEdges().front()->getNBEdge()->getDistance();
1693 }
1694 case 15: {
1695 return fabs(getParentEdges().front()->getNBEdge()->getDistance());
1696 }
1697 }
1698 return 0;
1699}
1700
1701
1702void
1703GNELane::drawOverlappedRoutes(const int numRoutes) const {
1704 // get middle point and angle
1707 // Push route matrix
1709 // translate to front
1710 glTranslated(0, 0, GLO_ROUTE + 1);
1711 // get middle
1712 GLHelper::drawText(toString(numRoutes) + " routes", center, 0, 1.8, RGBColor::BLACK, angle + 90);
1713 // pop route matrix
1715
1716}
1717
1718
1719void
1721 const auto& laneStopOffset = getParentEdges().front()->getNBEdge()->getLaneStruct(myIndex).laneStopOffset;
1722 // check conditions
1723 if (laneStopOffset.isDefined() && (laneStopOffset.getPermissions() & SVC_PASSENGER) != 0) {
1724 const Position& end = getLaneShape().back();
1725 const Position& f = getLaneShape()[-2];
1726 const double rot = RAD2DEG(atan2((end.x() - f.x()), (f.y() - end.y())));
1729 glTranslated(end.x(), end.y(), 1);
1730 glRotated(rot, 0, 0, 1);
1731 glTranslated(0, laneStopOffset.getOffset(), 0);
1732 glBegin(GL_QUADS);
1733 glVertex2d(-myDrawingConstants->getDrawingWidth(), 0.0);
1734 glVertex2d(-myDrawingConstants->getDrawingWidth(), 0.2);
1735 glVertex2d(myDrawingConstants->getDrawingWidth(), 0.2);
1736 glVertex2d(myDrawingConstants->getDrawingWidth(), 0.0);
1737 glEnd();
1739 }
1740}
1741
1742
1743bool
1745 return isWaterway(getParentEdges().front()->getNBEdge()->getPermissions(myIndex)) && s.showRails; // reusing the showRails setting
1746}
1747
1748
1749void
1751 // Draw direction indicators if the correspondient option is enabled
1752 if (s.showLaneDirection) {
1753 // improve visibility of superposed rail edges
1755 glColor3d(0.3, 0.3, 0.3);
1756 }
1757 // get width and sideOffset
1758 const double width = MAX2(NUMERICAL_EPS, (myDrawingConstants->getDrawingWidth() * 2 * myDrawingConstants->getExaggeration()));
1759 // push direction indicator matrix
1761 // move to front
1762 glTranslated(0, 0, 0.1);
1763 // iterate over shape
1764 for (int i = 0; i < (int) myLaneGeometry.getShape().size() - 1; ++i) {
1765 // push triangle matrix
1767 // move front
1768 glTranslated(myLaneGeometry.getShape()[i].x(), myLaneGeometry.getShape()[i].y(), 0.1);
1769 // rotate
1770 glRotated(myLaneGeometry.getShapeRotations()[i], 0, 0, 1);
1771 // calculate subwidth
1772 for (double subWidth = 0; subWidth < myLaneGeometry.getShapeLengths()[i]; subWidth += width) {
1773 // calculate length
1774 const double length = MIN2(width * 0.5, myLaneGeometry.getShapeLengths()[i] - subWidth);
1775 // draw triangle
1776 glBegin(GL_TRIANGLES);
1777 glVertex2d(-myDrawingConstants->getOffset(), -subWidth - length);
1778 glVertex2d(-myDrawingConstants->getOffset() - width * 0.25, -subWidth);
1779 glVertex2d(-myDrawingConstants->getOffset() + width * 0.25, -subWidth);
1780 glEnd();
1781 }
1782 // pop triangle matrix
1784 }
1785 // pop direction indicator matrix
1787 }
1788}
1789
1790
1791void
1793 // draw foot width 150mm, assume that distance between rail feet inner sides is reduced on both sides by 39mm with regard to the gauge
1794 // assume crosstie length of 181% gauge (2600mm for standard gauge)
1795 // first save current color (obtained from view configuration)
1796 const auto currentLaneColor = GLHelper::getColor();
1797 // Set current color
1798 GLHelper::setColor(currentLaneColor);
1799 // continue depending of detail
1801 // move
1802 glTranslated(0, 0, 0.1);
1803 // draw external crossbar
1804 const double crossbarWidth = 0.2 * myDrawingConstants->getExaggeration();
1805 // draw geometry
1809 // move
1810 glTranslated(0, 0, 0.01);
1811 // Set color gray
1812 glColor3d(0.8, 0.8, 0.8);
1813 // draw geometry
1817 // move
1818 glTranslated(0, 0, 0.01);
1819 // Set current color
1820 GLHelper::setColor(currentLaneColor);
1821 // Draw crossties
1824 myDrawingConstants->getOffset(), false);
1825 } else if (myShapeColors.size() > 0) {
1826 // draw colored box lines
1829 } else {
1830 // draw geometry with current color
1833 }
1834}
1835
1836
1837void
1839 // check all conditions for drawing textures
1840 if (!s.disableLaneIcons && (myLaneRestrictedTexturePositions.size() > 0)) {
1841 // Declare default width of icon (3)
1842 const double iconWidth = myDrawingConstants->getDrawingWidth() * 0.6;
1843 // Draw list of icons
1844 for (int i = 0; i < (int)myLaneRestrictedTexturePositions.size(); i++) {
1845 // Push draw matrix 2
1847 // Set white color
1848 glColor3d(1, 1, 1);
1849 // Translate matrix 2
1850 glTranslated(myLaneRestrictedTexturePositions.at(i).x(), myLaneRestrictedTexturePositions.at(i).y(), 0.1);
1851 // Rotate matrix 2
1852 glRotated(myLaneRestrictedTextureRotations.at(i), 0, 0, -1);
1853 glRotated(90, 0, 0, 1);
1854 // draw texture box depending of type of restriction
1857 } else if (isRestricted(SVC_BICYCLE)) {
1859 } else if (isRestricted(SVC_BUS)) {
1861 }
1862 // Pop draw matrix 2
1864 }
1865 }
1866}
1867
1868
1869void
1871 // draw a Start/endPoints if lane has a custom shape
1872 if ((myDrawingConstants->getDetail() <= GUIVisualizationSettings::Detail::GeometryPoint) && (getParentEdges().front()->getNBEdge()->getLaneStruct(myIndex).customShape.size() > 1)) {
1873 // obtain circle width and resolution
1874 const double circleWidth = GNEEdge::SNAP_RADIUS * MIN2((double)1, s.laneWidthExaggeration) / 2;
1875 // obtain custom shape
1876 const PositionVector& customShape = getParentEdges().front()->getNBEdge()->getLaneStruct(myIndex).customShape;
1877 // set color (override with special colors unless the color scheme is based on selection)
1878 if (drawUsingSelectColor() && s.laneColorer.getActive() != 1) {
1880 } else {
1881 GLHelper::setColor(s.junctionColorer.getSchemes()[0].getColor(2));
1882 }
1883 // push start matrix
1885 // move to shape start position
1886 glTranslated(customShape.front().x(), customShape.front().y(), 0.1);
1887 // draw circle
1889 // draw s depending of detail
1891 // move top
1892 glTranslated(0, 0, 0.1);
1893 // draw "S"
1894 GLHelper::drawText("S", Position(), 0.1, circleWidth, RGBColor::WHITE);
1895 }
1896 // pop start matrix
1898 // draw line between junction and start position
1900 // move top
1901 glTranslated(0, 0, 0.1);
1902 // set line width
1903 glLineWidth(4);
1904 // draw line
1905 GLHelper::drawLine(customShape.front(), getParentEdges().front()->getFromJunction()->getPositionInView());
1906 // pop line matrix
1908 // push start matrix
1910 // move to end position
1911 glTranslated(customShape.back().x(), customShape.back().y(), 0.1);
1912 // draw filled circle
1914 // draw "e" depending of detail
1916 // move top
1917 glTranslated(0, 0, 0.1);
1918 // draw "E"
1919 GLHelper::drawText("E", Position(), 0, circleWidth, RGBColor::WHITE);
1920 }
1921 // pop start matrix
1923 // draw line between Junction and end position
1925 // move top
1926 glTranslated(0, 0, 0.1);
1927 // set line width
1928 glLineWidth(4);
1929 // draw line
1930 GLHelper::drawLine(customShape.back(), getParentEdges().front()->getToJunction()->getPositionInView());
1931 // pop line matrix
1933 }
1934}
1935
1936
1937std::string
1939 return getParentEdges().front()->getID();
1940}
1941
1942
1943long
1944GNELane::onDefault(FXObject* obj, FXSelector sel, void* data) {
1945 myNet->getViewNet()->getViewParent()->getTLSEditorFrame()->handleMultiChange(this, obj, sel, data);
1946 return 1;
1947}
1948
1949
1950std::vector<GNEConnection*>
1952 // Declare a vector to save incoming connections
1953 std::vector<GNEConnection*> incomingConnections;
1954 // Obtain incoming edges if junction source was already created
1955 GNEJunction* junctionSource = getParentEdges().front()->getFromJunction();
1956 if (junctionSource) {
1957 // Iterate over incoming GNEEdges of junction
1958 for (const auto& incomingEdge : junctionSource->getGNEIncomingEdges()) {
1959 // Iterate over connection of incoming edges
1960 for (const auto& connection : incomingEdge->getGNEConnections()) {
1961 if (connection->getLaneTo()->getIndex() == getIndex()) {
1962 incomingConnections.push_back(connection);
1963 }
1964 }
1965 }
1966 }
1967 return incomingConnections;
1968}
1969
1970
1971std::vector<GNEConnection*>
1973 // Obtain GNEConnection of parent edge
1974 const std::vector<GNEConnection*>& edgeConnections = getParentEdges().front()->getGNEConnections();
1975 std::vector<GNEConnection*> outcomingConnections;
1976 // Obtain outgoing connections
1977 for (const auto& connection : edgeConnections) {
1978 if (connection->getLaneFrom()->getIndex() == getIndex()) {
1979 outcomingConnections.push_back(connection);
1980 }
1981 }
1982 return outcomingConnections;
1983}
1984
1985
1986void
1988 // update incoming connections of lane
1989 std::vector<GNEConnection*> incomingConnections = getGNEIncomingConnections();
1990 for (const auto& incomingConnection : incomingConnections) {
1991 incomingConnection->updateConnectionID();
1992 }
1993 // update outcoming connections of lane
1994 std::vector<GNEConnection*> outcomingConnections = getGNEOutcomingConnections();
1995 for (const auto& outcomingConnection : outcomingConnections) {
1996 outcomingConnection->updateConnectionID();
1997 }
1998}
1999
2000
2001double
2003 // factor should not be 0
2004 if (getParentEdges().front()->getNBEdge()->getFinalLength() > 0) {
2005 return MAX2(POSITION_EPS, (getLaneShape().length() / getParentEdges().front()->getNBEdge()->getFinalLength()));
2006 } else {
2007 return POSITION_EPS;
2008 };
2009}
2010
2011
2012void
2014 // Create basic commands
2015 std::string edgeDescPossibleMulti = toString(SUMO_TAG_EDGE);
2016 const int edgeSelSize = getParentEdges().front()->isAttributeCarrierSelected() ? myNet->getAttributeCarriers()->getNumberOfSelectedEdges() : 0;
2017 if (edgeSelSize && getParentEdges().front()->isAttributeCarrierSelected() && (edgeSelSize > 1)) {
2018 edgeDescPossibleMulti = toString(edgeSelSize) + " " + toString(SUMO_TAG_EDGE) + "s";
2019 }
2020 // create menu pane for edge operations
2021 FXMenuPane* edgeOperations = new FXMenuPane(ret);
2022 ret->insertMenuPaneChild(edgeOperations);
2023 if (edgeSelSize > 0) {
2024 new FXMenuCascade(ret, TLF("Edge operations (% selected)", toString(edgeSelSize)).c_str(), nullptr, edgeOperations);
2025 } else {
2026 new FXMenuCascade(ret, TL("Edge operations"), nullptr, edgeOperations);
2027 }
2028 // create menu commands for all edge operations
2029 GUIDesigns::buildFXMenuCommand(edgeOperations, TL("Split edge here"), nullptr, &parent, MID_GNE_EDGE_SPLIT);
2030 auto splitBothDirections = GUIDesigns::buildFXMenuCommand(edgeOperations, TL("Split edge in both directions here (no symmetric opposite edge)"), nullptr, &parent, MID_GNE_EDGE_SPLIT_BIDI);
2031 // check if allow split edge in both directions
2032 splitBothDirections->disable();
2033 const auto oppositeEdges = getParentEdges().front()->getOppositeEdges();
2034 if (oppositeEdges.size() == 0) {
2035 splitBothDirections->setText(TL("Split edge in both directions here (no opposite edge)"));
2036 } else {
2037 for (const auto& oppositeEdge : oppositeEdges) {
2038 // get reverse inner geometry
2039 const auto reverseGeometry = oppositeEdge->getNBEdge()->getInnerGeometry().reverse();
2040 if (reverseGeometry == getParentEdges().front()->getNBEdge()->getInnerGeometry()) {
2041 splitBothDirections->enable();
2042 splitBothDirections->setText(TL("Split edge in both directions here"));
2043 }
2044 }
2045 }
2046 GUIDesigns::buildFXMenuCommand(edgeOperations, TL("Set geometry endpoint here (shift-click)"), nullptr, &parent, MID_GNE_EDGE_EDIT_ENDPOINT);
2047 // restore geometry points depending of selection status
2048 if (getParentEdges().front()->isAttributeCarrierSelected()) {
2049 if (edgeSelSize == 1) {
2050 GUIDesigns::buildFXMenuCommand(edgeOperations, TL("Restore both geometry endpoints"), nullptr, &parent, MID_GNE_EDGE_RESET_ENDPOINT);
2051 } else {
2052 GUIDesigns::buildFXMenuCommand(edgeOperations, TL("Restore geometry endpoints of all selected edges"), nullptr, &parent, MID_GNE_EDGE_RESET_ENDPOINT);
2053 }
2054 } else {
2055 GUIDesigns::buildFXMenuCommand(edgeOperations, TL("Restore geometry endpoint (shift-click)"), nullptr, &parent, MID_GNE_EDGE_RESET_ENDPOINT);
2056 }
2057 GUIDesigns::buildFXMenuCommand(edgeOperations, TLF("Reverse %", edgeDescPossibleMulti), nullptr, &parent, MID_GNE_EDGE_REVERSE);
2058 auto reverse = GUIDesigns::buildFXMenuCommand(edgeOperations, TLF("Add reverse direction for %", edgeDescPossibleMulti), nullptr, &parent, MID_GNE_EDGE_ADD_REVERSE);
2059 if (getParentEdges().front()->getReverseEdge() != nullptr) {
2060 reverse->disable();
2061 }
2062 GUIDesigns::buildFXMenuCommand(edgeOperations, TLF("Add reverse disconnected direction for %", edgeDescPossibleMulti), nullptr, &parent, MID_GNE_EDGE_ADD_REVERSE_DISCONNECTED);
2063 GUIDesigns::buildFXMenuCommand(edgeOperations, TLF("Reset lengths for %", edgeDescPossibleMulti), nullptr, &parent, MID_GNE_EDGE_RESET_LENGTH);
2064 GUIDesigns::buildFXMenuCommand(edgeOperations, TLF("Straighten %", edgeDescPossibleMulti), nullptr, &parent, MID_GNE_EDGE_STRAIGHTEN);
2065 GUIDesigns::buildFXMenuCommand(edgeOperations, TLF("Smooth %", edgeDescPossibleMulti), nullptr, &parent, MID_GNE_EDGE_SMOOTH);
2066 GUIDesigns::buildFXMenuCommand(edgeOperations, TLF("Straighten elevation of %", edgeDescPossibleMulti), nullptr, &parent, MID_GNE_EDGE_STRAIGHTEN_ELEVATION);
2067 GUIDesigns::buildFXMenuCommand(edgeOperations, TLF("Smooth elevation of %", edgeDescPossibleMulti), nullptr, &parent, MID_GNE_EDGE_SMOOTH_ELEVATION);
2068}
2069
2070
2071void
2073 // Get icons
2074 FXIcon* pedestrianIcon = GUIIconSubSys::getIcon(GUIIcon::LANE_PEDESTRIAN);
2075 FXIcon* bikeIcon = GUIIconSubSys::getIcon(GUIIcon::LANE_BIKE);
2076 FXIcon* busIcon = GUIIconSubSys::getIcon(GUIIcon::LANE_BUS);
2077 FXIcon* greenVergeIcon = GUIIconSubSys::getIcon(GUIIcon::LANEGREENVERGE);
2078 // declare number of selected lanes
2079 int numSelectedLanes = 0;
2080 // if lane is selected, calculate number of restricted lanes
2081 bool edgeHasSidewalk = false;
2082 bool edgeHasBikelane = false;
2083 bool edgeHasBuslane = false;
2084 bool differentLaneShapes = false;
2086 const auto selectedLanes = myNet->getAttributeCarriers()->getSelectedLanes();
2087 // update numSelectedLanes
2088 numSelectedLanes = (int)selectedLanes.size();
2089 // iterate over selected lanes
2090 for (const auto& selectedLane : selectedLanes) {
2091 if (selectedLane->getParentEdges().front()->hasRestrictedLane(SVC_PEDESTRIAN)) {
2092 edgeHasSidewalk = true;
2093 }
2094 if (selectedLane->getParentEdges().front()->hasRestrictedLane(SVC_BICYCLE)) {
2095 edgeHasBikelane = true;
2096 }
2097 if (selectedLane->getParentEdges().front()->hasRestrictedLane(SVC_BUS)) {
2098 edgeHasBuslane = true;
2099 }
2100 if (selectedLane->getParentEdges().front()->getNBEdge()->getLaneStruct(selectedLane->getIndex()).customShape.size() != 0) {
2101 differentLaneShapes = true;
2102 }
2103 }
2104 } else {
2105 edgeHasSidewalk = getParentEdges().front()->hasRestrictedLane(SVC_PEDESTRIAN);
2106 edgeHasBikelane = getParentEdges().front()->hasRestrictedLane(SVC_BICYCLE);
2107 edgeHasBuslane = getParentEdges().front()->hasRestrictedLane(SVC_BUS);
2108 differentLaneShapes = getParentEdges().front()->getNBEdge()->getLaneStruct(myIndex).customShape.size() != 0;
2109 }
2110 // create menu pane for lane operations
2111 FXMenuPane* laneOperations = new FXMenuPane(ret);
2112 ret->insertMenuPaneChild(laneOperations);
2113 if (numSelectedLanes > 0) {
2114 new FXMenuCascade(ret, TLF("Lane operations (% selected)", toString(numSelectedLanes)).c_str(), nullptr, laneOperations);
2115 } else {
2116 new FXMenuCascade(ret, TL("Lane operations"), nullptr, laneOperations);
2117 }
2118 GUIDesigns::buildFXMenuCommand(laneOperations, TL("Duplicate lane"), nullptr, &parent, MID_GNE_LANE_DUPLICATE);
2119 GUIDesigns::buildFXMenuCommand(laneOperations, TL("Set custom lane shape"), nullptr, &parent, MID_GNE_LANE_EDIT_SHAPE);
2120 FXMenuCommand* resetCustomShape = GUIDesigns::buildFXMenuCommand(laneOperations, TL("Reset custom shape"), nullptr, &parent, MID_GNE_LANE_RESET_CUSTOMSHAPE);
2121 if (!differentLaneShapes) {
2122 resetCustomShape->disable();
2123 }
2124 FXMenuCommand* resetOppositeLane = GUIDesigns::buildFXMenuCommand(laneOperations, TL("Reset opposite lane"), nullptr, &parent, MID_GNE_LANE_RESET_OPPOSITELANE);
2125 if (getAttribute(GNE_ATTR_OPPOSITE).empty()) {
2126 resetOppositeLane->disable();
2127 }
2128 // Create panel for lane operations and insert it in ret
2129 FXMenuPane* addSpecialLanes = new FXMenuPane(laneOperations);
2130 ret->insertMenuPaneChild(addSpecialLanes);
2131 FXMenuPane* removeSpecialLanes = new FXMenuPane(laneOperations);
2132 ret->insertMenuPaneChild(removeSpecialLanes);
2133 FXMenuPane* transformSlanes = new FXMenuPane(laneOperations);
2134 ret->insertMenuPaneChild(transformSlanes);
2135 // Create menu comands for all add special lanes
2136 FXMenuCommand* addSidewalk = GUIDesigns::buildFXMenuCommand(addSpecialLanes, TL("Sidewalk"), pedestrianIcon, &parent, MID_GNE_LANE_ADD_SIDEWALK);
2137 FXMenuCommand* addBikelane = GUIDesigns::buildFXMenuCommand(addSpecialLanes, TL("Bike lane"), bikeIcon, &parent, MID_GNE_LANE_ADD_BIKE);
2138 FXMenuCommand* addBuslane = GUIDesigns::buildFXMenuCommand(addSpecialLanes, TL("Bus lane"), busIcon, &parent, MID_GNE_LANE_ADD_BUS);
2139 // if parent edge is selected, always add greenverge in front
2140 if (getParentEdges().front()->isAttributeCarrierSelected()) {
2141 GUIDesigns::buildFXMenuCommand(addSpecialLanes, TL("Green verge"), greenVergeIcon, &parent, MID_GNE_LANE_ADD_GREENVERGE_FRONT);
2142 } else {
2143 GUIDesigns::buildFXMenuCommand(addSpecialLanes, TL("Green verge (front)"), greenVergeIcon, &parent, MID_GNE_LANE_ADD_GREENVERGE_FRONT);
2144 GUIDesigns::buildFXMenuCommand(addSpecialLanes, TL("Green verge (back)"), greenVergeIcon, &parent, MID_GNE_LANE_ADD_GREENVERGE_BACK);
2145 }
2146 // Create menu comands for all remove special lanes and disable it
2147 FXMenuCommand* removeSidewalk = GUIDesigns::buildFXMenuCommand(removeSpecialLanes, TL("Sidewalk"), pedestrianIcon, &parent, MID_GNE_LANE_REMOVE_SIDEWALK);
2148 removeSidewalk->disable();
2149 FXMenuCommand* removeBikelane = GUIDesigns::buildFXMenuCommand(removeSpecialLanes, TL("Bike lane"), bikeIcon, &parent, MID_GNE_LANE_REMOVE_BIKE);
2150 removeBikelane->disable();
2151 FXMenuCommand* removeBuslane = GUIDesigns::buildFXMenuCommand(removeSpecialLanes, TL("Bus lane"), busIcon, &parent, MID_GNE_LANE_REMOVE_BUS);
2152 removeBuslane->disable();
2153 FXMenuCommand* removeGreenVerge = GUIDesigns::buildFXMenuCommand(removeSpecialLanes, TL("Green verge"), greenVergeIcon, &parent, MID_GNE_LANE_REMOVE_GREENVERGE);
2154 removeGreenVerge->disable();
2155 // Create menu comands for all transform special lanes and disable it
2156 FXMenuCommand* transformLaneToSidewalk = GUIDesigns::buildFXMenuCommand(transformSlanes, TL("Sidewalk"), pedestrianIcon, &parent, MID_GNE_LANE_TRANSFORM_SIDEWALK);
2157 FXMenuCommand* transformLaneToBikelane = GUIDesigns::buildFXMenuCommand(transformSlanes, TL("Bike lane"), bikeIcon, &parent, MID_GNE_LANE_TRANSFORM_BIKE);
2158 FXMenuCommand* transformLaneToBuslane = GUIDesigns::buildFXMenuCommand(transformSlanes, TL("Bus lane"), busIcon, &parent, MID_GNE_LANE_TRANSFORM_BUS);
2159 FXMenuCommand* transformLaneToGreenVerge = GUIDesigns::buildFXMenuCommand(transformSlanes, TL("Green verge"), greenVergeIcon, &parent, MID_GNE_LANE_TRANSFORM_GREENVERGE);
2160 // add menuCascade for lane operations
2161 new FXMenuCascade(laneOperations, TLF("Add restricted %", toString(SUMO_TAG_LANE)).c_str(), nullptr, addSpecialLanes);
2162 FXMenuCascade* cascadeRemoveSpecialLane = new FXMenuCascade(laneOperations, TLF("Remove restricted %", toString(SUMO_TAG_LANE)).c_str(), nullptr, removeSpecialLanes);
2163 new FXMenuCascade(laneOperations, TLF("Transform to restricted %", toString(SUMO_TAG_LANE)).c_str(), nullptr, transformSlanes);
2164 // Enable and disable options depending of current transform of the lane
2165 if (edgeHasSidewalk) {
2166 transformLaneToSidewalk->disable();
2167 addSidewalk->disable();
2168 removeSidewalk->enable();
2169 }
2170 if (edgeHasBikelane) {
2171 transformLaneToBikelane->disable();
2172 addBikelane->disable();
2173 removeBikelane->enable();
2174 }
2175 if (edgeHasBuslane) {
2176 transformLaneToBuslane->disable();
2177 addBuslane->disable();
2178 removeBuslane->enable();
2179 }
2181 transformLaneToGreenVerge->disable();
2182 removeGreenVerge->enable();
2183 }
2184 // Check if cascade menu must be disabled
2185 if (!edgeHasSidewalk && !edgeHasBikelane && !edgeHasBuslane && !isRestricted(SVC_IGNORING)) {
2186 cascadeRemoveSpecialLane->disable();
2187 }
2188 // for whatever reason, sonar complains in the next line that cascadeRemoveSpecialLane may leak, but fox does the cleanup
2189} // NOSONAR
2190
2191
2192void
2194 // Create basic commands
2195 std::string edgeDescPossibleMulti = toString(SUMO_TAG_EDGE);
2196 const int numSelectedEdges = getParentEdges().front()->isAttributeCarrierSelected() ? myNet->getAttributeCarriers()->getNumberOfSelectedEdges() : 0;
2197 if ((numSelectedEdges > 0) && getParentEdges().front()->isAttributeCarrierSelected() && (numSelectedEdges > 1)) {
2198 edgeDescPossibleMulti = toString(numSelectedEdges) + " " + toString(SUMO_TAG_EDGE) + "s";
2199 }
2200 // create menu pane for edge operations
2201 FXMenuPane* edgeOperations = new FXMenuPane(ret);
2202 ret->insertMenuPaneChild(edgeOperations);
2203 if (numSelectedEdges > 0) {
2204 new FXMenuCascade(ret, TLF("Template operations (% selected)", toString(numSelectedEdges)).c_str(), nullptr, edgeOperations);
2205 } else {
2206 new FXMenuCascade(ret, TL("Template operations"), nullptr, edgeOperations);
2207 }
2208 // create menu commands for all edge operations
2209 GUIDesigns::buildFXMenuCommand(edgeOperations, TL("Use edge as template"), nullptr, &parent, MID_GNE_EDGE_USEASTEMPLATE);
2210 auto applyTemplate = GUIDesigns::buildFXMenuCommand(edgeOperations, TL("Apply template"), nullptr, &parent, MID_GNE_EDGE_APPLYTEMPLATE);
2211 // check if disable apply template
2213 applyTemplate->disable();
2214 }
2215}
2216
2217
2218void
2220 // addreachability menu
2221 FXMenuPane* reachableByClass = new FXMenuPane(ret);
2222 ret->insertMenuPaneChild(reachableByClass);
2223 if (myNet->isNetRecomputed()) {
2224 new FXMenuCascade(ret, TL("Select reachable"), GUIIconSubSys::getIcon(GUIIcon::MODEVEHICLE), reachableByClass);
2225 for (const auto& vClass : SumoVehicleClassStrings.getStrings()) {
2226 GUIDesigns::buildFXMenuCommand(reachableByClass, vClass.c_str(), VClassIcons::getVClassIcon(SumoVehicleClassStrings.get(vClass)), &parent, MID_REACHABILITY);
2227 }
2228 } else {
2229 FXMenuCommand* menuCommand = GUIDesigns::buildFXMenuCommand(ret, TL("Select reachable (compute junctions)"), nullptr, nullptr, 0);
2230 menuCommand->handle(&parent, FXSEL(SEL_COMMAND, FXWindow::ID_DISABLE), nullptr);
2231 }
2232}
2233
2234/****************************************************************************/
NetworkEditMode
@brie enum for network edit modes
@ NETWORK_DELETE
mode for deleting network elements
@ NETWORK_MOVE
mode for moving network elements
@ NETWORK_ADDITIONAL
Mode for editing additionals.
@ NETWORK_TLS
mode for editing tls
@ NETWORK_SELECT
mode for selecting network elements
@ NETWORK_CONNECT
mode for connecting lanes
@ MID_GNE_ADDSELECT_EDGE
Add edge to selected items - menu entry.
Definition GUIAppEnum.h:849
@ MID_GNE_LANE_EDIT_SHAPE
edit lane shape
@ MID_GNE_LANE_TRANSFORM_BIKE
transform lane to bikelane
@ MID_GNE_EDGE_REVERSE
reverse an edge
@ MID_ADDSELECT
Add to selected items - menu entry.
Definition GUIAppEnum.h:485
@ MID_GNE_LANE_ADD_BUS
add busLane
@ MID_GNE_REMOVESELECT_EDGE
Remove edge from selected items - Menu Entry.
Definition GUIAppEnum.h:851
@ MID_GNE_EDGE_STRAIGHTEN_ELEVATION
interpolate z values linear between junctions
@ MID_GNE_EDGE_SMOOTH
smooth geometry
@ MID_GNE_LANE_RESET_CUSTOMSHAPE
reset custom shape
@ MID_GNE_EDGE_STRAIGHTEN
remove inner geometry
@ MID_GNE_LANE_TRANSFORM_BUS
transform lane to busLane
@ MID_COPY_EDGE_NAME
Copy edge name (for lanes only)
Definition GUIAppEnum.h:459
@ MID_GNE_LANE_DUPLICATE
duplicate a lane
@ MID_GNE_LANE_ADD_GREENVERGE_FRONT
add greenVerge front of current lane
@ MID_GNE_LANE_REMOVE_GREENVERGE
remove greenVerge
@ MID_GNE_EDGE_ADD_REVERSE_DISCONNECTED
add reverse edge disconnected (used for for spreadtype center)
@ MID_GNE_EDGE_SPLIT_BIDI
split an edge
@ MID_GNE_LANE_REMOVE_BIKE
remove bikelane
@ MID_GNE_LANE_RESET_OPPOSITELANE
reset opposite lane
@ MID_REACHABILITY
show reachability from a given lane
Definition GUIAppEnum.h:531
@ MID_GNE_EDGE_RESET_LENGTH
reset custom lengths
@ MID_GNE_LANE_REMOVE_BUS
remove busLane
@ MID_GNE_LANE_REMOVE_SIDEWALK
remove sidewalk
@ MID_GNE_EDGE_RESET_ENDPOINT
reset default geometry endpoints
@ MID_GNE_LANE_ADD_GREENVERGE_BACK
add greenVerge back of current lane
@ MID_GNE_EDGE_SMOOTH_ELEVATION
smooth elevation with regard to adjoining edges
@ MID_GNE_EDGE_ADD_REVERSE
add reverse edge
@ MID_GNE_EDGE_APPLYTEMPLATE
apply template
@ MID_GNE_EDGE_USEASTEMPLATE
use edge as tempalte
@ MID_GNE_LANE_ADD_SIDEWALK
add sidewalk
@ MID_GNE_RESET_GEOMETRYPOINT
reset geometry point
@ MID_GNE_LANE_TRANSFORM_SIDEWALK
transform lane to sidewalk
@ MID_GNE_LANE_ADD_BIKE
add bikelane
@ MID_GNE_EDGE_SPLIT
split an edge
@ MID_GNE_LANE_TRANSFORM_GREENVERGE
transform lane to greenVerge
@ MID_GNE_CUSTOM_GEOMETRYPOINT
set custom geometry point
@ MID_GNE_EDGE_EDIT_ENDPOINT
change default geometry endpoints
@ MID_REMOVESELECT
Remove from selected items - Menu Entry.
Definition GUIAppEnum.h:487
@ GLO_ROUTE
a route
@ GLO_JUNCTION
a junction
@ GLO_FRONTELEMENT
front element (used in netedit)
@ GLO_LANE
a lane
@ GLO_TEXTNAME
text element (used in netedit)
GUIViewObjectsHandler gViewObjectsHandler
@ LANE_PEDESTRIAN
@ LANEGREENVERGE
#define RAD2DEG(x)
Definition GeomHelper.h:36
#define WRITE_WARNINGF(...)
Definition MsgHandler.h:288
#define TL(string)
Definition MsgHandler.h:305
#define TLF(string,...)
Definition MsgHandler.h:307
const SVCPermissions SVCAll
all VClasses are allowed
SVCPermissions invertPermissions(SVCPermissions permissions)
negate the given permissions and ensure that only relevant bits are set
bool isRailway(SVCPermissions permissions)
Returns whether an edge with the given permissions is a (exclusive) railway edge.
bool isWaterway(SVCPermissions permissions)
Returns whether an edge with the given permissions is a waterway edge.
const std::string & getVehicleClassNames(SVCPermissions permissions, bool expand)
Returns the ids of the given classes, divided using a ' '.
SVCPermissions parseVehicleClasses(const std::string &allowedS)
Parses the given definition of allowed vehicle classes into the given containers Deprecated classes g...
bool canParseVehicleClasses(const std::string &classes)
Checks whether the given string contains only known vehicle classes.
StringBijection< SUMOVehicleClass > SumoVehicleClassStrings(sumoVehicleClassStringInitializer, SVC_CUSTOM2, false)
long long int SVCPermissions
bitset where each bit declares whether a certain SVC may use this edge/lane
SUMOVehicleClass
Definition of vehicle classes to differ between different lane usage and authority types.
@ SVC_SHIP
is an arbitrary ship
@ SVC_IGNORING
vehicles ignoring classes
@ SVC_RAIL_CLASSES
classes which drive on tracks
@ SVC_PASSENGER
vehicle is a passenger car (a "normal" car)
@ SVC_BICYCLE
vehicle is a bicycle
@ SVC_RAIL_FAST
vehicle that is allowed to drive on high-speed rail tracks
@ SVC_DRONE
@ SVC_AUTHORITY
authorities vehicles
@ SVC_BUS
vehicle is a bus
@ SVC_AIRCRAFT
@ SVC_PEDESTRIAN
pedestrian
@ SUMO_TAG_CONNECTION
connectioon between two lanes
@ SUMO_TAG_LANE
begin/end of the description of a single lane
@ SUMO_TAG_EDGE
begin/end of the description of an edge
LinkDirection
The different directions a link between two lanes may take (or a stream between two edges)....
@ PARTLEFT
The link is a partial left direction.
@ RIGHT
The link is a (hard) right direction.
@ TURN
The link is a 180 degree turn.
@ LEFT
The link is a (hard) left direction.
@ STRAIGHT
The link is a straight direction.
@ TURN_LEFTHAND
The link is a 180 degree turn (left-hand network)
@ PARTRIGHT
The link is a partial right direction.
@ NODIR
The link has no direction (is a dead end link)
LinkState
The right-of-way state of a link between two lanes used when constructing a NBTrafficLightLogic,...
@ LINKSTATE_ALLWAY_STOP
This is an uncontrolled, all-way stop link.
@ LINKSTATE_MAJOR
This is an uncontrolled, major link, may pass.
@ LINKSTATE_STOP
This is an uncontrolled, minor link, has to stop.
@ LINKSTATE_EQUAL
This is an uncontrolled, right-before-left link.
@ LINKSTATE_ZIPPER
This is an uncontrolled, zipper-merge link.
@ LINKSTATE_TL_OFF_BLINKING
The link is controlled by a tls which is off and blinks, has to brake.
@ LINKSTATE_MINOR
This is an uncontrolled, minor link, has to brake.
@ LINKSTATE_TL_OFF_NOSIGNAL
The link is controlled by a tls which is off, not blinking, may pass.
SumoXMLAttr
Numbers representing SUMO-XML - attributes.
@ SUMO_ATTR_DISALLOW
@ SUMO_ATTR_ALLOW
@ SUMO_ATTR_FROM_JUNCTION
@ SUMO_ATTR_SPEED
@ GNE_ATTR_STOPOFFSET
stop offset (virtual, used by edge and lanes)
@ SUMO_ATTR_VIA
@ GNE_ATTR_OPPOSITE
to busStop (used by personPlans)
@ SUMO_ATTR_TO_JUNCTION
@ GNE_ATTR_PARENT
parent of an additional element
@ SUMO_ATTR_CUSTOMSHAPE
whether a given shape is user-defined
@ GNE_ATTR_FROM_LANEID
from lane ID (used in GNEConnection)
@ GNE_ATTR_STOPOEXCEPTION
stop exceptions (virtual, used by edge and lanes)
@ SUMO_ATTR_SHAPE
edge: the shape in xml-definition
@ SUMO_ATTR_CHANGE_LEFT
@ SUMO_ATTR_INDEX
@ SUMO_ATTR_ENDOFFSET
@ SUMO_ATTR_ACCELERATION
@ GNE_ATTR_TO_LANEID
to lane ID (used in GNEConnection)
@ SUMO_ATTR_CHANGE_RIGHT
@ SUMO_ATTR_TYPE
@ SUMO_ATTR_ID
@ SUMO_ATTR_WIDTH
@ SUMO_ATTR_FRICTION
const double SUMO_const_laneWidth
Definition StdDefs.h:52
T MIN2(T a, T b)
Definition StdDefs.h:80
const double SUMO_const_laneMarkWidth
Definition StdDefs.h:55
T MAX2(T a, T b)
Definition StdDefs.h:86
std::string toString(const T &t, std::streamsize accuracy=gPrecision)
Definition ToString.h:46
A class that stores a 2D geometrical boundary.
Definition Boundary.h:39
static void drawLine(const Position &beg, double rot, double visLength)
Draws a thin line.
Definition GLHelper.cpp:433
static void setColor(const RGBColor &c)
Sets the gl-color to this value.
Definition GLHelper.cpp:649
static void drawOutlineCircle(double radius, double iRadius, int steps=8)
Draws an unfilled circle around (0,0)
Definition GLHelper.cpp:591
static void drawTriangleAtEnd(const Position &p1, const Position &p2, double tLength, double tWidth, const double extraOffset=0)
Draws a triangle at the end of the given line.
Definition GLHelper.cpp:624
static void drawTextAtEnd(const std::string &text, const PositionVector &shape, double x, const GUIVisualizationTextSettings &settings, const double scale)
draw text and the end of shape
Definition GLHelper.cpp:824
static void popMatrix()
pop matrix
Definition GLHelper.cpp:131
static RGBColor getColor()
gets the gl-color
Definition GLHelper.cpp:655
static void drawBoxLine(const Position &beg, double rot, double visLength, double width, double offset=0)
Draws a thick line.
Definition GLHelper.cpp:296
static void drawFilledCircleDetailled(const GUIVisualizationSettings::Detail d, const double radius)
Draws a filled circle around (0,0) depending of level of detail.
Definition GLHelper.cpp:534
static void pushMatrix()
push matrix
Definition GLHelper.cpp:118
static void drawInverseMarkings(const PositionVector &geom, const std::vector< double > &rots, const std::vector< double > &lengths, double maxLength, double spacing, double halfWidth, bool cl, bool cr, bool lefthand, double scale)
@bried draw the space between markings (in road color)
Definition GLHelper.cpp:886
static void drawText(const std::string &text, const Position &pos, const double layer, const double size, const RGBColor &col=RGBColor::BLACK, const double angle=0, const int align=0, double width=-1)
Definition GLHelper.cpp:742
static void drawCrossTies(const PositionVector &geom, const std::vector< double > &rots, const std::vector< double > &lengths, double length, double spacing, double halfWidth, double offset, bool lessDetail)
draw crossties for railroads or pedestrian crossings
Definition GLHelper.cpp:843
const std::string getID() const
get ID (all Attribute Carriers have one)
bool isAttributeCarrierSelected() const
check if attribute carrier is selected
bool isMarkedForDrawingFront() const
check if this AC is marked for drawing front
bool mySelected
boolean to check if this AC is selected (more quickly as checking GUIGlObjectStorage)
std::string getCommonAttribute(const Parameterised *parameterised, SumoXMLAttr key) const
void setCommonAttribute(SumoXMLAttr key, const std::string &value, GNEUndoList *undoList)
const std::string & getTagStr() const
get tag assigned to this object in string format
bool drawUsingSelectColor() const
check if attribute carrier must be drawn using selecting color.
void drawInLayer(const double typeOrLayer, const double extraOffset=0) const
draw element in the given layer, or in front if corresponding flag is enabled
GNENet * myNet
pointer to net
bool isCommonValid(SumoXMLAttr key, const std::string &value) const
GNENet * getNet() const
get pointer to net
const GNETagProperties * myTagProperty
reference to tagProperty associated with this attribute carrier
bool myPossibleCandidate
flag to mark this element as possible candidate
bool mySpecialCandidate
flag to mark this element as special candidate
bool myInvalidCandidate
flag to mark this element as invalid candidate
bool myTargetCandidate
flag to mark this element as target candidate
bool myConflictedCandidate
flag to mark this element as conflicted candidate
bool mySourceCandidate
flag to mark this element as source candidate
static void changeAttribute(GNEAttributeCarrier *AC, SumoXMLAttr key, const std::string &value, GNEUndoList *undoList, const bool force=false)
change attribute
void calculateContourExtrudedShape(const GUIVisualizationSettings &s, const GUIVisualizationSettings::Detail d, const GUIGlObject *glObject, const PositionVector &shape, const double layer, const double extrusionWidth, const double scale, const bool closeFirstExtrem, const bool closeLastExtrem, const double offset, const GNESegment *segment, const GUIGlObject *boundaryParent, const bool addToSelectedObjects=true) const
calculate contour extruded (used in elements formed by a central shape)
Boundary getContourBoundary() const
get contour boundary
bool drawDottedContours(const GUIVisualizationSettings &s, const GUIVisualizationSettings::Detail d, const GNEAttributeCarrier *AC, const double lineWidth, const bool addOffset) const
draw dotted contours (basics, select, delete, inspect...)
void calculateContourAllGeometryPoints(const GUIVisualizationSettings &s, const GUIVisualizationSettings::Detail d, const GUIGlObject *glObject, const PositionVector &shape, const double layer, const double radius, const double scale, const bool calculatePosOverShape) const
calculate contour for all geometry points
struct for saving subordinated elements (Junction->Edge->Lane->(Additional | DemandElement)
ProtectElements * getProtectElements() const
get protect elements modul
A road/street connecting two junctions (netedit-version)
Definition GNEEdge.h:53
NBEdge * getNBEdge() const
returns the internal NBEdge
Definition GNEEdge.cpp:829
static const double SNAP_RADIUS
Definition GNEEdge.h:305
const GNEHierarchicalContainerParents< GNEAdditional * > & getParentAdditionals() const
get parent additionals
const GNEHierarchicalContainerParents< GNEDemandElement * > & getParentDemandElements() const
get parent demand elements
const GNEHierarchicalContainerParents< GNEEdge * > & getParentEdges() const
get parent edges
const GNEHierarchicalContainerChildren< GNEGenericData * > & getChildGenericDatas() const
return child generic data elements
const GNEHierarchicalContainerParents< GNEGenericData * > & getParentGenericDatas() const
get parent demand elements
const GNEHierarchicalContainerChildren< GNEAdditional * > & getChildAdditionals() const
return child additionals
const GNEHierarchicalContainerChildren< GNEDemandElement * > & getChildDemandElements() const
return child demand elements
void setEdgeTemplate(const GNEEdge *edge)
set edge template
GNEEdgeTemplate * getEdgeTemplate() const
get edge template (to copy attributes from)
TemplateEditor * getTemplateEditor() const
get template editor
static RGBColor colorForLinksState(FXuint state)
return the color for each linkstate
static const StringBijection< FXuint > LinkStateNames
long names for link states
const std::vector< GNEEdge * > & getGNEIncomingEdges() const
Returns incoming GNEEdges.
std::vector< GNEConnection * > getGNEConnections() const
Returns all GNEConnections vinculated with this junction.
class lane2lane connection geometry
FOX-declaration.
Definition GNELane.h:52
const GNELane * myLane
lane
Definition GNELane.h:84
double myInternalDrawingWidth
internal lane drawing width (used for drawing selected lanes)
Definition GNELane.h:93
void update(const GUIVisualizationSettings &s)
update lane drawing constants
Definition GNELane.cpp:77
GUIVisualizationSettings::Detail myDetail
detail level
Definition GNELane.h:99
bool drawAsRailway() const
draw as railway
Definition GNELane.cpp:151
bool drawSuperposed() const
draw superposed
Definition GNELane.cpp:157
double getExaggeration() const
get exaggeration
Definition GNELane.cpp:121
double myExaggeration
exaggeration
Definition GNELane.h:87
double getDrawingWidth() const
get lane drawing width
Definition GNELane.cpp:127
double getInternalDrawingWidth() const
get internal lane drawing width
Definition GNELane.cpp:133
double myDrawingWidth
lane drawing width
Definition GNELane.h:90
bool myDrawAsRailway
draw as railway
Definition GNELane.h:102
double myOffset
lane offset
Definition GNELane.h:96
double getOffset() const
get lane offset
Definition GNELane.cpp:139
bool myDrawSuperposed
draw supersposed (reduced width so that the lane markings below are visible)
Definition GNELane.h:105
GUIVisualizationSettings::Detail getDetail() const
get detail
Definition GNELane.cpp:145
This lane is powered by an underlying GNEEdge and basically knows how to draw itself.
Definition GNELane.h:46
GNELane2laneConnection myLane2laneConnections
lane2lane connections
Definition GNELane.h:366
const PositionVector & getLaneShape() const
get elements shape
Definition GNELane.cpp:221
long onDefault(FXObject *, FXSelector, void *)
multiplexes message to two targets
Definition GNELane.cpp:1944
bool checkDrawDeleteContourSmall() const
check if draw delete contour small (pink/white)
Definition GNELane.cpp:406
const GNELane2laneConnection & getLane2laneConnections() const
get Lane2laneConnection struct
Definition GNELane.cpp:693
~GNELane()
Destructor.
Definition GNELane.cpp:195
std::string getParentName() const
Returns the name of the parent object (if any)
Definition GNELane.cpp:1938
std::string getAttribute(SumoXMLAttr key) const
Definition GNELane.cpp:699
void drawLaneStopOffset(const GUIVisualizationSettings &s) const
draw laneStopOffset
Definition GNELane.cpp:1720
void drawSelectedLane(const GUIVisualizationSettings &s) const
draw selected lane
Definition GNELane.cpp:1082
bool checkDrawMoveContour() const
check if draw move contour (red)
Definition GNELane.cpp:430
std::vector< double > myLaneRestrictedTextureRotations
Rotations of textures of restricted lanes.
Definition GNELane.h:353
bool allowPedestrians() const
check if current lane allow pedestrians
Definition GNELane.cpp:209
void drawMarkingsAndBoundings(const GUIVisualizationSettings &s) const
draw lane markings
Definition GNELane.cpp:1148
const RGBColor * mySpecialColor
optional special color
Definition GNELane.h:357
Position getPositionInView() const
Returns position of hierarchical element in view.
Definition GNELane.cpp:326
bool isAttributeComputed(SumoXMLAttr key) const
Definition GNELane.cpp:889
bool drawAsWaterway(const GUIVisualizationSettings &s) const
whether to draw this lane as a waterways
Definition GNELane.cpp:1744
bool checkDrawDeleteContour() const
check if draw delete contour (pink/white)
Definition GNELane.cpp:388
double getLengthGeometryFactor() const
get length geometry factor
Definition GNELane.cpp:2002
bool isAttributeEnabled(SumoXMLAttr key) const
Definition GNELane.cpp:875
void drawDirectionIndicators(const GUIVisualizationSettings &s) const
direction indicators for lanes
Definition GNELane.cpp:1750
bool checkDrawSelectContour() const
check if draw select contour (blue)
Definition GNELane.cpp:412
void updateGeometry()
update pre-computed geometry information
Definition GNELane.cpp:249
void setMoveShape(const GNEMoveResult &moveResult)
set move shape
Definition GNELane.cpp:1010
void deleteGLObject()
delete element
Definition GNELane.cpp:507
std::string getAttributeForSelection(SumoXMLAttr key) const
method for getting the attribute in the context of object selection
Definition GNELane.cpp:768
GUIGLObjectPopupMenu * getPopUpMenu(GUIMainWindow &app, GUISUMOAbstractView &parent)
Returns an own popup-menu.
Definition GNELane.cpp:523
int getIndex() const
returns the index of the lane
Definition GNELane.cpp:651
double getExaggeration(const GUIVisualizationSettings &s) const
return exaggeration associated with this GLObject
Definition GNELane.cpp:633
void removeGeometryPoint(const Position clickedPosition, GNEUndoList *undoList)
remove geometry point in the clicked position
Definition GNELane.cpp:454
GUIGeometry myLaneGeometry
lane geometry
Definition GNELane.h:341
bool checkDrawOverContour() const
check if draw over contour (orange)
Definition GNELane.cpp:368
void drawShapeEdited(const GUIVisualizationSettings &s) const
draw shape edited
Definition GNELane.cpp:1101
void drawOverlappedRoutes(const int numRoutes) const
draw overlapped routes
Definition GNELane.cpp:1703
void updateGLObject()
update GLObject (geometry, ID, etc.)
Definition GNELane.cpp:516
GNEMoveOperation * getMoveOperation()
get move operation
Definition GNELane.cpp:442
void buildLaneOperations(GUISUMOAbstractView &parent, GUIGLObjectPopupMenu *ret)
build lane operations contextual menu
Definition GNELane.cpp:2072
GNELane()
FOX needs this.
Definition GNELane.cpp:183
std::vector< GNEConnection * > getGNEOutcomingConnections()
returns a vector with the outgoing GNEConnections of this lane
Definition GNELane.cpp:1972
DrawingConstants * myDrawingConstants
LaneDrawingConstants.
Definition GNELane.h:344
const std::vector< double > & getShapeRotations() const
get rotations of the single shape parts
Definition GNELane.cpp:231
void buildTemplateOperations(GUISUMOAbstractView &parent, GUIGLObjectPopupMenu *ret)
build template oerations contextual menu
Definition GNELane.cpp:2193
bool setMultiColor(const GUIVisualizationSettings &s, const GUIColorer &c, RGBColor &col) const
sets multiple colors according to the current scheme index and some lane function
Definition GNELane.cpp:1567
void calculateLaneContour(const GUIVisualizationSettings &s, const double layer) const
calculate contour
Definition GNELane.cpp:1439
void drawTLSLinkNo(const GUIVisualizationSettings &s) const
draw TLS link Number
Definition GNELane.cpp:1266
const Parameterised::Map & getACParametersMap() const
get parameters map
Definition GNELane.cpp:901
double getLaneParametricLength() const
returns the parameteric length of the lane
Definition GNELane.cpp:670
RGBColor setLaneColor(const GUIVisualizationSettings &s) const
set color according to edit mode and visualisation settings
Definition GNELane.cpp:1457
bool isValid(SumoXMLAttr key, const std::string &value)
Definition GNELane.cpp:814
std::vector< GNEConnection * > getGNEIncomingConnections()
returns a vector with the incoming GNEConnections of this lane
Definition GNELane.cpp:1951
bool isRestricted(SUMOVehicleClass vclass) const
check if this lane is restricted
Definition GNELane.cpp:687
const DrawingConstants * getDrawingConstants() const
get lane drawing constants (previously calculated in drawGL())
Definition GNELane.cpp:243
int myIndex
The index of this lane.
Definition GNELane.h:338
void drawLaneAsRailway() const
draw lane as railway
Definition GNELane.cpp:1792
void setIndex(int index)
Definition GNELane.cpp:657
void drawGL(const GUIVisualizationSettings &s) const
Draws the object.
Definition GNELane.cpp:480
bool checkDrawFromContour() const
check if draw from contour (green)
Definition GNELane.cpp:332
void setSpecialColor(const RGBColor *Color2, double colorValue=std::numeric_limits< double >::max())
Definition GNELane.cpp:907
const GUIGeometry & getLaneGeometry() const
get lane geometry
Definition GNELane.cpp:215
Boundary getCenteringBoundary() const
Returns the boundary to which the view shall be centered in order to show the object.
Definition GNELane.cpp:639
void drawArrows(const GUIVisualizationSettings &s) const
draw lane arrows
Definition GNELane.cpp:1303
void updateCenteringBoundary(const bool updateGrid)
update centering boundary (implies change in RTREE)
Definition GNELane.cpp:645
void drawLane(const GUIVisualizationSettings &s, const double layer) const
draw lane
Definition GNELane.cpp:1028
double mySpecialColorValue
optional value that corresponds to which the special color corresponds
Definition GNELane.h:360
void drawChildren(const GUIVisualizationSettings &s) const
draw children
Definition GNELane.cpp:1127
bool checkDrawRelatedContour() const
check if draw related contour (cyan)
Definition GNELane.cpp:358
std::vector< Position > myLaneRestrictedTexturePositions
Position of textures of restricted lanes.
Definition GNELane.h:350
void commitMoveShape(const GNEMoveResult &moveResult, GNEUndoList *undoList)
commit move shape
Definition GNELane.cpp:1019
double getLaneShapeLength() const
returns the length of the lane's shape
Definition GNELane.cpp:681
void drawStartEndGeometryPoints(const GUIVisualizationSettings &s) const
draw start and end geometry points
Definition GNELane.cpp:1870
std::vector< RGBColor > myShapeColors
The color of the shape parts (cached)
Definition GNELane.h:363
double getColorValue(const GUIVisualizationSettings &s, int activeScheme) const
return value for lane coloring according to the given scheme
Definition GNELane.cpp:1591
bool checkDrawToContour() const
check if draw from contour (magenta)
Definition GNELane.cpp:345
bool setFunctionalColor(int activeScheme, RGBColor &col) const
sets the color according to the current scheme index and some lane function
Definition GNELane.cpp:1553
void updateConnectionIDs()
update IDs of incoming connections of this lane
Definition GNELane.cpp:1987
void buildRechableOperations(GUISUMOAbstractView &parent, GUIGLObjectPopupMenu *ret)
build rechable operations contextual menu
Definition GNELane.cpp:2219
void drawLane2LaneConnections() const
draw lane to lane connections
Definition GNELane.cpp:1391
void buildEdgeOperations(GUISUMOAbstractView &parent, GUIGLObjectPopupMenu *ret)
build edge operations contextual menu
Definition GNELane.cpp:2013
const std::vector< double > & getShapeLengths() const
get lengths of the single shape parts
Definition GNELane.cpp:237
PositionVector getAttributePositionVector(SumoXMLAttr key) const
Definition GNELane.cpp:756
void drawLinkNo(const GUIVisualizationSettings &s) const
draw link Number
Definition GNELane.cpp:1229
double getSpeed() const
returns the current speed of lane
Definition GNELane.cpp:664
void drawTextures(const GUIVisualizationSettings &s) const
draw lane textures
Definition GNELane.cpp:1838
void setAttribute(SumoXMLAttr key, const std::string &value, GNEUndoList *undoList)
Definition GNELane.cpp:778
GNEEdge * getParentEdge() const
get parent edge
Definition GNELane.cpp:203
GNEMoveOperation * calculateMoveShapeOperation(const GUIGlObject *obj, const PositionVector originalShape, const bool maintainShapeClosed)
calculate move shape operation
move operation
move result
PositionVector shapeToUpdate
shape to update (edited in moveElement)
std::vector< GNELane * > getSelectedLanes() const
get selected lanes
int getNumberOfSelectedEdges() const
get number of selected edges
void deleteLane(GNELane *lane, GNEUndoList *undoList, bool recomputeConnections)
removes lane
Definition GNENet.cpp:637
GNEPathManager * getDataPathManager()
get data path manager
Definition GNENet.cpp:180
GNEPathManager * getDemandPathManager()
get demand path manager
Definition GNENet.cpp:174
GNENetHelper::AttributeCarriers * getAttributeCarriers() const
get all attribute carriers used in this net
Definition GNENet.cpp:144
bool isNetRecomputed() const
check if net require recomputing
Definition GNENet.cpp:1604
GNEPathManager * getNetworkPathManager()
get network path manager
Definition GNENet.cpp:168
NBEdgeCont & getEdgeCont()
returns the NBEdgeCont of the underlying netbuilder
Definition GNENet.cpp:2205
GNEViewNet * getViewNet() const
get view net
Definition GNENet.cpp:2193
GNEContour myNetworkElementContour
network element contour
bool myShapeEdited
flag to check if element shape is being edited
void setNetworkElementID(const std::string &newID)
set network element id
bool isShapeEdited() const
check if shape is being edited
bool drawCandidateEdgesWithSpecialColor() const
draw candidate edges with special color (Only for candidates, special and conflicted)
void invalidatePathCalculator()
invalidate pathCalculator
PathCalculator * getPathCalculator()
obtain instance of PathCalculator
void drawLanePathElements(const GUIVisualizationSettings &s, const GNELane *lane) const
draw lane path elements
GNEPathCreator * getPathCreator() const
get path creator module
bool controlsEdge(GNEEdge *edge) const
whether the given edge is controlled by the currently edited tlDef
void handleMultiChange(GNELane *lane, FXObject *obj, FXSelector sel, void *data)
update phase definition for the current traffic light and phase
SumoXMLTag getTag() const
get Tag vinculated with this attribute Property
void end()
End undo command sub-group. If the sub-group is still empty, it will be deleted; otherwise,...
void begin(GUIIcon icon, const std::string &description)
Begin undo command sub-group with current supermode. This begins a new group of commands that are tre...
GNELane * getLaneFront() const
get front lane or a pointer to nullptr
const GNEViewNetHelper::EditModes & getEditModes() const
get edit modes
const GNEViewNetHelper::EditNetworkElementShapes & getEditNetworkElementShapes() const
get Edit Shape module
GNEViewNetHelper::InspectedElements & getInspectedElements()
get inspected elements
const GNEViewNetHelper::NetworkViewOptions & getNetworkViewOptions() const
get network view options
GNEViewParent * getViewParent() const
get the net object
bool checkOverLockedElement(const GUIGlObject *GLObject, const bool isSelected) const
check if given element is locked (used for drawing select and delete contour)
bool checkSelectEdges() const
check if select edges (toggle using button or shift)
GNEUndoList * getUndoList() const
get the undoList object
const GNEViewNetHelper::ViewObjectsSelector & getViewObjectsSelector() const
get objects under cursor
GNEDeleteFrame * getDeleteFrame() const
get frame for delete elements
GNETLSEditorFrame * getTLSEditorFrame() const
get frame for NETWORK_TLS
GNEInspectorFrame * getInspectorFrame() const
get frame for inspect elements
GNERouteFrame * getRouteFrame() const
get frame for DEMAND_ROUTE
static FXMenuCommand * buildFXMenuCommand(FXComposite *p, const std::string &text, FXIcon *icon, FXObject *tgt, FXSelector sel, const bool disable=false)
build menu command
The popup menu of a globject.
void insertMenuPaneChild(FXMenuPane *child)
Insert a sub-menu pane in this GUIGLObjectPopupMenu.
GUIGlObject * getGLObject() const
The object that belongs to this popup-menu.
const std::vector< double > & getShapeRotations() const
The rotations of the single shape parts.
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
static void drawGeometry(const GUIVisualizationSettings::Detail d, const GUIGeometry &geometry, const double width, double offset=0)
draw geometry
static double calculateRotation(const Position &first, const Position &second)
return angle between two points (used in geometric calculations)
const PositionVector & getShape() const
The shape of the additional element.
void updateGeometry(const PositionVector &shape)
update entire geometry
const std::vector< double > & getShapeLengths() const
The lengths of the single shape parts.
const std::string & getMicrosimID() const
Returns the id of the object as known to microsim.
void buildPositionCopyEntry(GUIGLObjectPopupMenu *ret, const GUIMainWindow &app, bool addSeparator=true) const
Builds an entry which allows to copy the cursor position if geo projection is used,...
void buildShowParamsPopupEntry(GUIGLObjectPopupMenu *ret, bool addSeparator=true)
Builds an entry which allows to open the parameter window.
void buildCenterPopupEntry(GUIGLObjectPopupMenu *ret, bool addSeparator=true)
Builds an entry which allows to center to the object.
void buildNameCopyPopupEntry(GUIGLObjectPopupMenu *ret, bool addSeparator=true)
Builds entries which allow to copy the name / typed name into the clipboard.
void buildPopupHeader(GUIGLObjectPopupMenu *ret, GUIMainWindow &app, bool addSeparator=true)
Builds the header.
GUIGlObjectType getType() const
Returns the type of the object as coded in GUIGlObjectType.
static FXIcon * getIcon(const GUIIcon which)
returns a icon previously defined in the enum GUIIcon
T getColor(const double value) const
const std::vector< T > & getSchemes() const
const GUIVisualizationSettings & getVisualisationSettings() const
get visualization settings (read only)
double m2p(double meter) const
meter-to-pixels conversion method
virtual Position getPositionInformation() const
Returns the cursor's x/y position within the network.
GUIGLObjectPopupMenu * getPopup() const
ge the current popup-menu
static GUIGlID getTexture(GUITexture which)
returns a texture previously defined in the enum GUITexture
static void drawTexturedBox(int which, double size)
Draws a named texture as a box with the given size.
bool checkBoundaryParentObject(const GUIGlObject *GLObject, const double layer, const GUIGlObject *parent)
Stores the information about how to visualize structures.
GUIVisualizationSizeSettings addSize
bool disableLaneIcons
whether drawing is performed in left-hand networks
GUIVisualizationTextSettings drawLinkJunctionIndex
Detail getDetailLevel(const double exaggeration) const
return the detail level
bool showRails
Information whether rails shall be drawn.
GUIVisualizationCandidateColorSettings candidateColorSettings
candidate color settings
double laneWidthExaggeration
The lane exaggeration (upscale thickness)
bool lefthand
whether drawing is performed in left-hand networks
GUIVisualizationColorSettings colorSettings
color settings
GUIVisualizationDottedContourSettings dottedContourSettings
dotted contour settings
static const RGBColor & getLinkColor(const LinkState &ls, bool realistic=false)
map from LinkState to color constants
double scale
information about a lane's width (temporary, used for a single view)
bool showLaneDirection
Whether to show direction indicators for lanes.
bool drawForViewObjectsHandler
whether drawing is performed for the purpose of selecting objects in view using ViewObjectsHandler
bool showLinkDecals
Information whether link textures (arrows) shall be drawn.
GUIColorer laneColorer
The lane colorer.
bool laneShowBorders
Information whether lane borders shall be drawn.
GUIVisualizationTextSettings drawLinkTLIndex
double selectorFrameScale
the current selection scaling in netedit (set in SelectorFrame)
bool spreadSuperposed
Whether to improve visualisation of superposed (rail) edges.
GUIColorer junctionColorer
The junction colorer.
std::string edgeParam
key for coloring by edge parameter
GUIVisualizationNeteditSizeSettings neteditSizeSettings
netedit size settings
static double naviDegree(const double angle)
static FXColor getFXColor(const RGBColor &col)
converts FXColor to RGBColor
Definition MFXUtils.cpp:145
NBEdge * retrieve(const std::string &id, bool retrieveExtracted=false) const
Returns the edge that has the given id.
The representation of a single edge during network building.
Definition NBEdge.h:92
double getLaneSpeed(int lane) const
get lane speed
Definition NBEdge.cpp:2231
void setPermittedChanging(int lane, SVCPermissions changeLeft, SVCPermissions changeRight)
set allowed classes for changing to the left and right from the given lane
Definition NBEdge.cpp:4514
SVCPermissions getPermissions(int lane=-1) const
get the union of allowed classes over all lanes or for a specific lane
Definition NBEdge.cpp:4523
void setPermissions(SVCPermissions permissions, int lane=-1)
set allowed/disallowed classes for the given lane or for all lanes if -1 is given
Definition NBEdge.cpp:4486
void setSpeed(int lane, double speed)
set lane specific speed (negative lane implies set for all lanes)
Definition NBEdge.cpp:4438
NBNode * getToNode() const
Returns the destination node of the edge.
Definition NBEdge.h:552
Lane & getLaneStruct(int lane)
Definition NBEdge.h:1440
bool isBidiRail(bool ignoreSpread=false) const
whether this edge is part of a bidirectional railway
Definition NBEdge.cpp:770
const std::string & getID() const
Definition NBEdge.h:1540
void setLaneWidth(int lane, double width)
set lane specific width (negative lane implies set for all lanes)
Definition NBEdge.cpp:4309
void setAcceleration(int lane, bool accelRamp)
marks one lane as acceleration lane
Definition NBEdge.cpp:4470
bool isBidiEdge(bool checkPotential=false) const
whether this edge is part of a bidirectional edge pair
Definition NBEdge.cpp:782
int getNumLanes() const
Returns the number of lanes.
Definition NBEdge.h:526
void setFriction(int lane, double friction)
set lane specific friction (negative lane implies set for all lanes)
Definition NBEdge.cpp:4454
std::string getLaneID(int lane) const
get lane ID
Definition NBEdge.cpp:4161
void setLaneShape(int lane, const PositionVector &shape)
sets a custom lane shape
Definition NBEdge.cpp:4478
NBNode * getFromNode() const
Returns the origin node of the edge.
Definition NBEdge.h:545
static const double UNSPECIFIED_WIDTH
unspecified lane width
Definition NBEdge.h:346
void setEndOffset(int lane, double offset)
set lane specific end-offset (negative lane implies set for all lanes)
Definition NBEdge.cpp:4392
Represents a single node (junction) during network building.
Definition NBNode.h:66
LinkDirection getDirection(const NBEdge *const incoming, const NBEdge *const outgoing, bool leftHand=false) const
Returns the representation of the described stream's direction.
Definition NBNode.cpp:2487
LinkState getLinkState(const NBEdge *incoming, const NBEdge *outgoing, int fromLane, int toLane, bool mayDefinitelyPass, const std::string &tlID) const
get link state
Definition NBNode.cpp:2572
std::map< std::string, std::string > Map
parameters map
const Parameterised::Map & getParametersMap() const
Returns the inner key/value map.
A point in 2D or 3D with translation and scaling methods.
Definition Position.h:37
double x() const
Returns the x-position.
Definition Position.h:52
double z() const
Returns the z-position.
Definition Position.h:62
double angleTo2D(const Position &other) const
returns the angle in the plane of the vector pointing from here to the other position (in radians bet...
Definition Position.h:283
double y() const
Returns the y-position.
Definition Position.h:57
A list of positions.
double length2D() const
Returns the length.
double beginEndAngle() const
returns the angle in radians of the line connecting the first and the last position
double length() const
Returns the length.
double rotationDegreeAtOffset(double pos) const
Returns the rotation at the given length.
Position positionAtOffset(double pos, double lateralOffset=0) const
Returns the position at the given length.
double nearest_offset_to_point2D(const Position &p, bool perpendicular=true) const
return the nearest offest to point 2D
int indexOfClosest(const Position &p, bool twoD=false) const
Position positionAtOffset2D(double pos, double lateralOffset=0, bool extrapolateBeyond=false) const
Returns the position at the given length.
static const RGBColor WHITE
Definition RGBColor.h:195
static const RGBColor ORANGE
Definition RGBColor.h:194
static const RGBColor CYAN
Definition RGBColor.h:192
static const RGBColor GREEN
Definition RGBColor.h:189
static RGBColor fromHSV(double h, double s, double v)
Converts the given hsv-triplet to rgb, inspired by http://alvyray.com/Papers/CG/hsv2rgb....
Definition RGBColor.cpp:403
static const RGBColor BLACK
Definition RGBColor.h:196
RGBColor changedBrightness(int change, int toChange=3) const
Returns a new color with altered brightness.
Definition RGBColor.cpp:200
void setOffset(const double offset)
set offset
bool isDefined() const
check if stopOffset was defined
void setExceptions(const std::string permissions)
set exceptions (used in netedit)
std::string getExceptions() const
get exceptions (used in netedit)
double getOffset() const
get offset
std::vector< std::string > getStrings() const
get all strings
T get(const std::string &str) const
get key
static double toDouble(const std::string &sData)
converts a string into the double value described by it by calling the char-type converter
static bool toBool(const std::string &sData)
converts a string into the bool value described by it by calling the char-type converter
static FXIcon * getVClassIcon(const SUMOVehicleClass vc)
returns icon associated to the given vClass
NetworkEditMode networkEditMode
the current Network edit mode
bool isCurrentSupermodeDemand() const
@check if current supermode is Demand
bool isCurrentSupermodeData() const
@check if current supermode is Data
bool isCurrentSupermodeNetwork() const
@check if current supermode is Network
GNENetworkElement * getEditedNetworkElement() const
pointer to edited network element
static void drawLockIcon(const GUIVisualizationSettings::Detail d, const GNEAttributeCarrier *AC, GUIGlObjectType type, const Position position, const double exaggeration, const double size=0.5, const double offsetx=0, const double offsety=0)
draw lock icon
bool editingElevation() const
check if we're editing elevation
bool showDemandElements() const
check if show demand elements checkbox is enabled
static const RGBColor special
color for selected special candidate element (Usually selected using shift+click)
static const RGBColor conflict
color for selected conflict candidate element (Usually selected using ctrl+click)
static const RGBColor invalid
color for invalid elements
static const RGBColor target
color for selected candidate target
static const RGBColor possible
color for possible candidate element
static const RGBColor source
color for selected candidate source
RGBColor selectedEdgeColor
edge selection color
RGBColor selectedLaneColor
lane selection color
static const RGBColor editShapeColor
color for edited shapes (Junctions, crossings and connections)
static const double segmentWidth
width of dotted contour segments
static const double laneGeometryPointRadius
moving lane geometry point radius
static const double junctionBubbleRadius
junction bubble radius
double getExaggeration(const GUIVisualizationSettings &s, const GUIGlObject *o, double factor=20) const
return the drawing size including exaggeration and constantSize values
bool show(const GUIGlObject *o) const
whether to show the text
double width
This lane's width.
Definition NBEdge.h:176
StopOffset laneStopOffset
stopOffsets.second - The stop offset for vehicles stopping at the lane's end. Applies if vClass is in...
Definition NBEdge.h:173
PositionVector customShape
A custom shape for this lane set by the user.
Definition NBEdge.h:189
double endOffset
This lane's offset to the intersection begin.
Definition NBEdge.h:169
std::string type
the type of this lane
Definition NBEdge.h:192
std::string oppositeID
An opposite lane ID, if given.
Definition NBEdge.h:179
SVCPermissions changeRight
List of vehicle types that are allowed to change right from this lane.
Definition NBEdge.h:166
double friction
The friction on this lane.
Definition NBEdge.h:154
SVCPermissions changeLeft
List of vehicle types that are allowed to change Left from this lane.
Definition NBEdge.h:163
bool accelRamp
Whether this lane is an acceleration lane.
Definition NBEdge.h:182