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-2026 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>
33#include <netedit/GNENet.h>
41
42#include "GNELane.h"
43#include "GNEInternalLane.h"
44#include "GNEConnection.h"
45#include "GNEEdgeTemplate.h"
46
47// ===========================================================================
48// FOX callback mapping
49// ===========================================================================
50
51// Object implementation
52FXIMPLEMENT(GNELane, FXDelegator, 0, 0)
53
54// ===========================================================================
55// method definitions
56// ===========================================================================
57
58// ---------------------------------------------------------------------------
59// GNELane::LaneDrawingConstants - methods
60// ---------------------------------------------------------------------------
61
63 myLane(lane) {
64}
65
66
67void
69 // get NBEdge
70 const auto& NBEdge = myLane->getParentEdge()->getNBEdge();
71 // get lane struct
72 const auto& laneStruct = myLane->getParentEdges().front()->getNBEdge()->getLaneStruct(myLane->getIndex());
73 // get selection scale
74 const double selectionScale = myLane->isAttributeCarrierSelected() || myLane->getParentEdges().front()->isAttributeCarrierSelected() ? s.selectorFrameScale : 1;
75 // get lane width
76 const double laneWidth = (laneStruct.width == -1 ? SUMO_const_laneWidth : laneStruct.width);
77 // calculate exaggeration
78 myExaggeration = selectionScale * s.laneWidthExaggeration;
79 // get detail level
81 // check if draw lane as railway
82 myDrawAsRailway = isRailway(laneStruct.permissions) && ((laneStruct.permissions & SVC_BUS) == 0) && s.showRails;
83 // adjust rest of parameters depending if draw as railway
84 if (myDrawAsRailway) {
85 // draw as railway: assume standard gauge of 1435mm when lane width is not set
86 myDrawingWidth = (laneWidth == SUMO_const_laneWidth ? 1.4350 : laneWidth) * myExaggeration;
87 // calculate internal drawing width
89 } else {
90 // calculate exaggerated drawing width
91 myDrawingWidth = laneWidth * myExaggeration * 0.5;
92 // calculate internal drawing width
94 }
95 // check if draw superposed
97 // adjust parameters depending of superposing
98 if (myDrawSuperposed) {
99 // apply offset
100 myOffset = myDrawingWidth * 0.5;
101 // reduce width
102 myDrawingWidth *= 0.4;
104 } else {
105 // restore offset
106 myOffset = 0;
107 }
108}
109
110
111double
113 return myExaggeration;
114}
115
116
117double
119 return myDrawingWidth;
120}
121
122
123double
125 return myInternalDrawingWidth;
126}
127
128
129double
131 return myOffset;
132}
133
134
137 return myDetail;
138}
139
140
141bool
143 return myDrawAsRailway;
144}
145
146
147bool
149 return myDrawSuperposed;
150}
151
152
153// ---------------------------------------------------------------------------
154// GNELane - methods
155// ---------------------------------------------------------------------------
156#ifdef _MSC_VER
157#pragma warning(push)
158#pragma warning(disable: 4355) // mask warning about "this" in initializers
159#endif
160GNELane::GNELane(GNEEdge* edge, const int index) :
161 GNENetworkElement(edge->getNet(), edge->getNBEdge()->getLaneID(index), SUMO_TAG_LANE),
163 myIndex(index),
165 mySpecialColor(nullptr),
168 // set parents
169 setParent<GNEEdge*>(edge);
170 // this is needed for open edge popup menu
171 setGLObjectParent(edge);
172 // update centering boundary without updating grid
174}
175
176
178 GNENetworkElement(nullptr, "dummyConstructorGNELane", SUMO_TAG_LANE),
179 myMoveElementLane(new GNEMoveElementLane(this)),
180 myIndex(-1),
181 myDrawingConstants(nullptr),
182 mySpecialColor(nullptr),
183 mySpecialColorValue(-1),
184 myLane2laneConnections(this) {
185}
186#ifdef _MSC_VER
187#pragma warning(pop)
188#endif
189
191 if (myDrawingConstants) {
192 delete myDrawingConstants;
193 }
194}
195
196
201
202
205 return &(getParentEdges().front()->getNBEdge()->getLaneStruct(myIndex));
206}
207
208
209const Parameterised*
211 return &(getParentEdges().front()->getNBEdge()->getLaneStruct(myIndex));
212}
213
214
215GNEEdge*
217 return getParentEdges().front();
218}
219
220
221bool
223 return (getParentEdges().front()->getNBEdge()->getPermissions(myIndex) & SVC_PEDESTRIAN) > 0;
224}
225
226
227const GUIGeometry&
229 return myLaneGeometry;
230}
231
232
233const PositionVector&
235 if (getParentEdges().front()->getNBEdge()->getLaneStruct(myIndex).customShape.size() > 0) {
236 return getParentEdges().front()->getNBEdge()->getLaneStruct(myIndex).customShape;
237 } else {
238 return getParentEdges().front()->getNBEdge()->getLaneShape(myIndex);
239 }
240}
241
242
243const std::vector<double>&
247
248
249const std::vector<double>&
253
254
259
260
261void
263 // Clear texture containers
266 // get lane shape and extend if is too short
267 auto laneShape = getLaneShape();
268 if (laneShape.length2D() < 1) {
269 laneShape.extrapolate2D(1 - laneShape.length2D());
270 }
271 // Obtain lane shape of NBEdge
273 // update connections
275 // update additionals children associated with this lane
276 for (const auto& additional : getParentAdditionals()) {
277 additional->updateGeometry();
278 }
279 // update additionals parents associated with this lane
280 for (const auto& additional : getChildAdditionals()) {
281 additional->updateGeometry();
282 }
283 // update partial demand elements parents associated with this lane
284 for (const auto& demandElement : getParentDemandElements()) {
285 demandElement->updateGeometry();
286 }
287 // update partial demand elements children associated with this lane
288 for (const auto& demandElement : getChildDemandElements()) {
289 demandElement->updateGeometry();
290 }
291 // Update geometry of parent generic datas that have this edge as parent
292 for (const auto& additionalParent : getParentGenericDatas()) {
293 additionalParent->updateGeometry();
294 }
295 // Update geometry of additionals generic datas vinculated to this edge
296 for (const auto& childAdditionals : getChildGenericDatas()) {
297 childAdditionals->updateGeometry();
298 }
299 // compute geometry of path elements elements vinculated with this lane (depending of showDemandElements)
301 for (const auto& childAdditional : getChildAdditionals()) {
302 childAdditional->computePathElement();
303 }
304 for (const auto& childDemandElement : getChildDemandElements()) {
305 childDemandElement->computePathElement();
306 }
307 for (const auto& childGenericData : getChildGenericDatas()) {
308 childGenericData->computePathElement();
309 }
310 }
311 // in Move mode, connections aren't updated
313 // Update incoming connections of this lane
314 const auto incomingConnections = getGNEIncomingConnections();
315 for (const auto& connection : incomingConnections) {
316 connection->updateGeometry();
317 }
318 // Update outgoings connections of this lane
319 const auto outGoingConnections = getGNEOutcomingConnections();
320 for (const auto& connection : outGoingConnections) {
321 connection->markConnectionGeometryDeprecated();
322 connection->updateGeometry();
323 }
324 }
325 // if lane has enought length for show textures of restricted lanes
326 if ((getLaneShapeLength() > 4)) {
327 // if lane is restricted
329 // get values for position and rotation of icons
330 for (int i = 2; i < getLaneShapeLength() - 1; i += 15) {
333 }
334 }
335 }
336}
337
338
341 return getLaneShape().positionAtOffset2D(getLaneShape().length2D() * 0.5);
342}
343
344
345bool
347 const auto& inspectedElements = myNet->getViewNet()->getInspectedElements();
348 // check if we're inspecting a connection
349 if (inspectedElements.isInspectingSingleElement() && (inspectedElements.getFirstAC()->getTagProperty()->getTag() == SUMO_TAG_CONNECTION) &&
350 inspectedElements.getFirstAC()->getAttribute(GNE_ATTR_FROM_LANEID) == getID()) {
351 return true;
352 } else {
353 return false;
354 }
355}
356
357
358bool
360 const auto& inspectedElements = myNet->getViewNet()->getInspectedElements();
361 // check if we're inspecting a connection
362 if (inspectedElements.isInspectingSingleElement() && (inspectedElements.getFirstAC()->getTagProperty()->getTag() == SUMO_TAG_CONNECTION) &&
363 inspectedElements.getFirstAC()->getAttribute(GNE_ATTR_TO_LANEID) == getID()) {
364 return true;
365 } else {
366 return false;
367 }
368}
369
370
371bool
373 // check opened popup
374 if (myNet->getViewNet()->getPopup()) {
375 return myNet->getViewNet()->getPopup()->getGLObject() == this;
377 // check if we're creating a access
379 return (templateAC && (templateAC->getTagProperty()->getTag() == SUMO_TAG_ACCESS) && (getAttribute(SUMO_ATTR_ALLOW) == "pedestrian"));
380 } else {
381 return false;
382 }
383}
384
385
386bool
388 // get modes and viewParent (for code legibility)
389 const auto& modes = myNet->getViewNet()->getEditModes();
390 const auto& viewParent = myNet->getViewParent();
391 // check if we're selecting edges in additional mode
392 if (modes.isCurrentSupermodeNetwork() && (modes.networkEditMode == NetworkEditMode::NETWORK_ADDITIONAL)) {
393 if (viewParent->getAdditionalFrame()->getViewObjetsSelector()->isNetworkElementSelected(this)) {
394 return true;
395 } else if (viewParent->getAdditionalFrame()->getViewObjetsSelector()->getTag() == myTagProperty->getTag()) {
397 } else {
398 return false;
399 }
400 } else {
401 return false;
402 }
403}
404
405
406bool
408 // first check if we're selecting edges or lanes
410 return false;
411 } else {
412 // get edit modes
413 const auto& editModes = myNet->getViewNet()->getEditModes();
414 // check if we're in delete mode
415 if (editModes.isCurrentSupermodeNetwork() && (editModes.networkEditMode == NetworkEditMode::NETWORK_DELETE)) {
417 } else {
418 return false;
419 }
420 }
421}
422
423
424bool
426 return false;
427}
428
429
430bool
432 // first check if we're selecting edges or lanes
434 return false;
435 } else {
436 // get edit modes
437 const auto& editModes = myNet->getViewNet()->getEditModes();
438 // check if we're in select mode
439 if (editModes.isCurrentSupermodeNetwork() && (editModes.networkEditMode == NetworkEditMode::NETWORK_SELECT)) {
441 } else {
442 return false;
443 }
444 }
445}
446
447
448bool
450 // check if we're editing this network element
452 if (editedNetworkElement) {
453 return editedNetworkElement == this;
454 } else {
455 return false;
456 }
457}
458
459
460void
462 // update lane drawing constan
464 // calculate layer
465 double layer = GLO_LANE;
466 if (getParentEdges().front()->isMarkedForDrawingFront()) {
467 layer = GLO_FRONTELEMENT;
469 layer = GLO_JUNCTION + 2;
470 }
471 // check drawing conditions
473 // draw lane
474 drawLane(s, layer);
475 // draw lock icon
477 // draw dotted contour
479 }
480 // calculate contour (always before children)
481 calculateLaneContour(s, layer);
482 // draw children
483 drawChildren(s);
484}
485
486
487void
489 // Check if edge can be deleted
491 myNet->deleteLane(this, myNet->getUndoList(), false);
492 }
493}
494
495
496void
500
501
502
505 // first obtain edit mode (needed because certain Commands depend of current edit mode)
507 // get mouse position
508 const auto mousePosition = myNet->getViewNet()->getPositionInformation();
509 GUIGLObjectPopupMenu* ret = new GUIGLObjectPopupMenu(app, parent, this);
510 buildPopupHeader(ret, app);
512 // build copy names entry
513 if (editMode != NetworkEditMode::NETWORK_TLS) {
514 GUIDesigns::buildFXMenuCommand(ret, TL("Copy parent edge name to clipboard"), nullptr, ret, MID_COPY_EDGE_NAME);
516 }
517 // stop if we're in data mode
519 return ret;
520 }
521 // build lane selection
524 } else {
526 }
527 // build edge selection
530 } else {
532 }
533 // add separator
534 new FXMenuSeparator(ret);
535 // delete lane
538 }
539 // stop if we're in data mode
541 return ret;
542 }
543 // add separator
544 new FXMenuSeparator(ret);
545 if (editMode != NetworkEditMode::NETWORK_TLS) {
546 // build show parameters menu
549 // add separator
550 new FXMenuSeparator(ret);
551 // build position copy entry
552 buildPositionCopyEntry(ret, app);
553 }
554 // check if we're in supermode network
556 // create end point
557 FXMenuCommand* resetEndPoints = GUIDesigns::buildFXMenuCommand(ret, TL("Reset edge end points"), nullptr, &parent, MID_GNE_RESET_GEOMETRYPOINT);
558 // enable or disable reset end points
559 if (getParentEdges().front()->hasCustomEndPoints()) {
560 resetEndPoints->enable();
561 } else {
562 resetEndPoints->disable();
563 }
564 // check if we clicked over a geometry point
565 if ((editMode == NetworkEditMode::NETWORK_MOVE) && getParentEdges().front()->clickedOverGeometryPoint(mousePosition)) {
566 GUIDesigns::buildFXMenuCommand(ret, TL("Set custom Geometry Point"), nullptr, &parent, MID_GNE_CUSTOM_GEOMETRYPOINT);
567 }
568 // add separator
569 new FXMenuSeparator(ret);
570 //build operations
571 if ((editMode != NetworkEditMode::NETWORK_CONNECT) && (editMode != NetworkEditMode::NETWORK_TLS)) {
572 // build edge operations
573 buildEdgeOperations(parent, ret);
574 // build lane operations
575 buildLaneOperations(parent, ret);
576 // build template operations
577 buildTemplateOperations(parent, ret);
578 // add separator
579 new FXMenuSeparator(ret);
580 // build rechable operations
581 buildRechableOperations(parent, ret);
582 } else if (editMode == NetworkEditMode::NETWORK_TLS) {
584 GUIDesigns::buildFXMenuCommand(ret, TL("Select state for all links from this edge:"), nullptr, nullptr, 0);
585 const std::vector<std::string> names = GNEInternalLane::LinkStateNames.getStrings();
586 for (auto it : names) {
587 FXuint state = GNEInternalLane::LinkStateNames.get(it);
588 FXMenuRadio* mc = new FXMenuRadio(ret, it.c_str(), this, FXDataTarget::ID_OPTION + state);
591 }
592 }
593 } else {
594 FXMenuCommand* mc = GUIDesigns::buildFXMenuCommand(ret, TL("Additional options available in 'Inspect Mode'"), nullptr, nullptr, 0);
595 mc->handle(&parent, FXSEL(SEL_COMMAND, FXWindow::ID_DISABLE), nullptr);
596 }
597 // build shape positions menu
598 if (editMode != NetworkEditMode::NETWORK_TLS) {
599 new FXMenuSeparator(ret);
600 // get lane shape
601 const auto& laneShape = myLaneGeometry.getShape();
602 // get variables
603 const double pos = laneShape.nearest_offset_to_point2D(mousePosition);
604 const Position firstAnglePos = laneShape.positionAtOffset2D(pos - 0.001);
605 const Position secondAnglePos = laneShape.positionAtOffset2D(pos);
606 const double angle = firstAnglePos.angleTo2D(secondAnglePos);
607
608 // build menu commands
609 GUIDesigns::buildFXMenuCommand(ret, TL("Shape pos: ") + toString(pos), nullptr, nullptr, 0);
610 GUIDesigns::buildFXMenuCommand(ret, TL("Length pos: ") + toString(pos * getLaneParametricLength() / getLaneShapeLength()), nullptr, nullptr, 0);
611 if (getParentEdges().front()->getNBEdge()->getDistance() != 0) {
612 GUIDesigns::buildFXMenuCommand(ret, TL("Distance: ") + toString(getParentEdges().front()->getNBEdge()->getDistancAt(pos)), nullptr, nullptr, 0);
613 }
614 GUIDesigns::buildFXMenuCommand(ret, TL("Height: ") + toString(firstAnglePos.z()), nullptr, nullptr, 0);
615 GUIDesigns::buildFXMenuCommand(ret, TL("Angle: ") + toString((GeomHelper::naviDegree(angle))), nullptr, nullptr, 0);
616 }
617 }
618 return ret;
619}
620
621
622double
624 return s.addSize.getExaggeration(s, this);
625}
626
627
632
633
634void
635GNELane::updateCenteringBoundary(const bool /*updateGrid*/) {
636 // nothing to update
637}
638
639
640int
642 return myIndex;
643}
644
645
646void
648 myIndex = index;
649 setNetworkElementID(getParentEdges().front()->getNBEdge()->getLaneID(index));
650}
651
652
653double
655 return getParentEdges().front()->getNBEdge()->getLaneSpeed(myIndex);
656}
657
658
659double
661 double laneParametricLength = getParentEdges().front()->getNBEdge()->getLoadedLength();
662 if (laneParametricLength > 0) {
663 return laneParametricLength;
664 } else {
665 throw ProcessError(TL("Lane Parametric Length cannot be never 0"));
666 }
667}
668
669
670double
674
675
676bool
678 return getParentEdges().front()->getNBEdge()->getPermissions(myIndex) == vclass;
679}
680
681
686
687
688std::string
690 const NBEdge* edge = getParentEdges().front()->getNBEdge();
691 switch (key) {
692 case SUMO_ATTR_ID:
693 return getMicrosimID();
695 return getParentEdges().front()->getFromJunction()->getID();
697 return getParentEdges().front()->getToJunction()->getID();
698 case SUMO_ATTR_SPEED:
699 return toString(edge->getLaneSpeed(myIndex));
700 case SUMO_ATTR_ALLOW:
708 case SUMO_ATTR_WIDTH:
710 return "default";
711 } else {
712 return toString(edge->getLaneStruct(myIndex).width);
713 }
715 return toString(edge->getLaneStruct(myIndex).friction);
720 case SUMO_ATTR_SHAPE:
725 case SUMO_ATTR_TYPE:
726 return edge->getLaneStruct(myIndex).type;
727 case SUMO_ATTR_INDEX:
728 return toString(myIndex);
734 } else {
735 return "";
736 }
737 case GNE_ATTR_PARENT:
738 return getParentEdges().front()->getID();
739 default:
740 return getCommonAttribute(key);
741 }
742}
743
744
745double
749
750
755
756
759 switch (key) {
760 case SUMO_ATTR_SHAPE:
762 return getParentEdges().front()->getNBEdge()->getLaneStruct(myIndex).customShape;
763 default:
765 }
766}
767
768
769std::string
771 std::string result = getAttribute(key);
772 if ((key == SUMO_ATTR_ALLOW || key == SUMO_ATTR_DISALLOW) && result.find("all") != std::string::npos) {
773 result += " " + getVehicleClassNames(SVCAll, true);
774 }
775 return result;
776}
777
778
779void
780GNELane::setAttribute(SumoXMLAttr key, const std::string& value, GNEUndoList* undoList) {
781 switch (key) {
782 case SUMO_ATTR_ID:
783 throw InvalidArgument("Modifying attribute '" + toString(key) + "' of " + getTagStr() + " isn't allowed");
784 case SUMO_ATTR_SPEED:
785 case SUMO_ATTR_ALLOW:
789 case SUMO_ATTR_WIDTH:
793 case SUMO_ATTR_SHAPE:
796 case SUMO_ATTR_TYPE:
797 case SUMO_ATTR_INDEX:
799 // special case for stop offset, because affects to stopOffsetExceptions (#15297)
800 if (canParse<double>(value) && (parse<double>(value) == 0)) {
802 }
803 GNEChange_Attribute::changeAttribute(this, key, value, undoList);
804 break;
806 GNEChange_Attribute::changeAttribute(this, key, value, undoList);
807 break;
808 default:
809 setCommonAttribute(key, value, undoList);
810 break;
811 }
812}
813
814
815bool
816GNELane::isValid(SumoXMLAttr key, const std::string& value) {
817 switch (key) {
818 case SUMO_ATTR_ID:
819 case SUMO_ATTR_INDEX:
820 return false;
821 case SUMO_ATTR_SPEED:
822 return canParse<double>(value);
823 case SUMO_ATTR_ALLOW:
827 return canParseVehicleClasses(value);
828 case SUMO_ATTR_WIDTH:
829 if (value.empty() || (value == "default")) {
830 return true;
831 } else {
832 return canParse<double>(value) && ((parse<double>(value) > 0) || (parse<double>(value) == NBEdge::UNSPECIFIED_WIDTH));
833 }
836 return canParse<double>(value) && (parse<double>(value) >= 0);
838 return canParse<bool>(value);
839 case SUMO_ATTR_SHAPE:
841 // A lane shape can either be empty or have more than 1 element
842 if (value.empty()) {
843 return true;
844 } else if (canParse<PositionVector>(value)) {
845 return parse<PositionVector>(value).size() > 1;
846 }
847 return false;
848 case GNE_ATTR_OPPOSITE: {
849 if (value.empty()) {
850 return true;
851 } else {
852 NBEdge* oppEdge = myNet->getEdgeCont().retrieve(value.substr(0, value.rfind("_")));
853 if (oppEdge == nullptr || oppEdge->getLaneID(oppEdge->getNumLanes() - 1) != value) {
854 return false;
855 }
856 NBEdge* edge = getParentEdges().front()->getNBEdge();
857 if (oppEdge->getFromNode() != edge->getToNode() || oppEdge->getToNode() != edge->getFromNode()) {
858 WRITE_WARNINGF(TL("Opposite lane '%' does not connect the same nodes as edge '%'!"), value, edge->getID());
859 return false;
860 }
861 return true;
862 }
863 }
864 case SUMO_ATTR_TYPE:
865 return true;
867 return canParse<double>(value) && (parse<double>(value) >= 0);
869 return canParseVehicleClasses(value);
870 default:
871 return isCommonAttributeValid(key, value);
872 }
873}
874
875
876bool
878 switch (key) {
879 case SUMO_ATTR_ID:
880 case SUMO_ATTR_INDEX:
881 return false;
883 return getParentEdges().front()->getNBEdge()->getLaneStruct(myIndex).laneStopOffset.getOffset() > 0;
884 default:
885 return true;
886 }
887}
888
889
890bool
892 const NBEdge* edge = getParentEdges().front()->getNBEdge();
893 switch (key) {
894 case SUMO_ATTR_WIDTH:
896 default:
897 return false;
898 }
899}
900
901
902void
903GNELane::setSpecialColor(const RGBColor* color, double colorValue) {
904 mySpecialColor = color;
905 mySpecialColorValue = colorValue;
906}
907
908// ===========================================================================
909// private
910// ===========================================================================
911
912void
913GNELane::setAttribute(SumoXMLAttr key, const std::string& value) {
914 // get parent edge
915 NBEdge* edge = getParentEdges().front()->getNBEdge();
916 // get template editor
918 // check if we have to update template
919 const bool updateTemplate = templateEditor->getEdgeTemplate() ? (templateEditor->getEdgeTemplate()->getID() == getParentEdges().front()->getID()) : false;
920 switch (key) {
921 case SUMO_ATTR_ID:
922 case SUMO_ATTR_INDEX:
923 throw InvalidArgument("Modifying attribute '" + toString(key) + "' of " + getTagStr() + " isn't allowed");
924 case SUMO_ATTR_SPEED:
925 edge->setSpeed(myIndex, parse<double>(value));
926 break;
927 case SUMO_ATTR_ALLOW:
929 break;
932 break;
935 break;
938 break;
939 case SUMO_ATTR_WIDTH:
940 if (value.empty() || (value == "default")) {
942 } else {
943 edge->setLaneWidth(myIndex, parse<double>(value));
944 }
945 // update edge parent boundary
946 getParentEdges().front()->updateCenteringBoundary(true);
947 break;
949 edge->setFriction(myIndex, parse<double>(value));
950 break;
952 edge->setEndOffset(myIndex, parse<double>(value));
953 break;
955 edge->setAcceleration(myIndex, parse<bool>(value));
956 break;
957 case SUMO_ATTR_SHAPE:
959 // set new shape
960 edge->setLaneShape(myIndex, parse<PositionVector>(value));
961 // update edge parent boundary
962 getParentEdges().front()->updateCenteringBoundary(true);
963 break;
964 case GNE_ATTR_OPPOSITE: {
965 if (value != "") {
966 NBEdge* oppEdge = myNet->getEdgeCont().retrieve(value.substr(0, value.rfind("_")));
967 oppEdge->getLaneStruct(oppEdge->getNumLanes() - 1).oppositeID = getID();
968 } else {
969 // reset prior oppEdge if existing
970 const std::string oldValue = getParentEdges().front()->getNBEdge()->getLaneStruct(myIndex).oppositeID;
971 NBEdge* oppEdge = myNet->getEdgeCont().retrieve(oldValue.substr(0, oldValue.rfind("_")));
972 if (oppEdge != nullptr) {
973 oppEdge->getLaneStruct(oppEdge->getNumLanes() - 1).oppositeID = "";
974 }
975 }
976 getParentEdges().front()->getNBEdge()->getLaneStruct(myIndex).oppositeID = value;
977 break;
978 }
979 case SUMO_ATTR_TYPE:
980 edge->getLaneStruct(myIndex).type = value;
981 break;
983 if (value.empty()) {
985 } else {
986 edge->getLaneStruct(myIndex).laneStopOffset.setOffset(parse<double>(value));
987 }
988 break;
991 break;
992 default:
993 setCommonAttribute(key, value);
994 break;
995 }
996 // update template
997 if (updateTemplate) {
998 templateEditor->setEdgeTemplate(getParentEdges().front());
999 }
1000 // invalidate demand path calculator
1002}
1003
1004
1005void
1006GNELane::drawLane(const GUIVisualizationSettings& s, const double layer) const {
1007 // Push layer matrix
1009 // translate to layer
1010 drawInLayer(layer);
1011 // set lane colors
1012 RGBColor laneColor = setLaneColor(s);
1013 // never draw when at full transparency
1014 if (laneColor.alpha() != 0) {
1015 // Check if lane has to be draw as railway and if isn't being drawn for selecting
1017 // draw as railway
1019 } else if (myShapeColors.size() > 0) {
1020 // draw geometry with own colors
1023 } else {
1024 // draw geometry with current color
1026 double drawingWidth = myDrawingConstants->getDrawingWidth();
1028 drawingWidth = myNet->getViewNet()->m2p(drawingWidth);
1029 }
1032 }
1033 // if lane is selected, draw a second lane over it
1035 // draw start end shape points
1037 // check if draw details
1039 // draw markings
1040 drawMarkingsAndBoundings(s, laneColor);
1041 // Draw direction indicators
1043 // draw lane textures
1044 drawTextures(s);
1045 // draw lane arrows
1046 drawArrows(s, laneColor);
1047 // draw link numbers
1048 drawLinkNo(s);
1049 // draw TLS link numbers
1050 drawTLSLinkNo(s);
1051 // draw stopOffsets
1053 }
1054 // draw shape edited
1055 drawShapeEdited(s);
1056 }
1057 // Pop layer matrix
1059}
1060
1061
1062void
1064 // only draw if lane is selected
1065 if (drawUsingSelectColor()) {
1066 // Push matrix
1068 // move back
1069 glTranslated(0, 0, 0.1);
1070 // set selected edge color
1072 // draw geometry with current color
1075 // Pop matrix
1077 }
1078}
1079
1080
1081void
1083 // if shape is being edited, draw point and green line
1084 if (myShapeEdited) {
1085 // push shape edited matrix
1087 // translate
1089 // set selected edge color
1091 // draw shape around
1094 // move front
1095 glTranslated(0, 0, 1);
1096 // draw geometry points
1101 // Pop shape edited matrix
1103 }
1104}
1105
1106
1107void
1109 // draw additional children
1110 for (const auto& additional : getChildAdditionals()) {
1111 if (!additional->getTagProperty()->isListedElement()) {
1112 additional->drawGL(s);
1113 }
1114 }
1115 // draw demand element children
1116 for (const auto& demandElement : getChildDemandElements()) {
1117 if (!demandElement->getTagProperty()->isPlacedInRTree()) {
1118 demandElement->drawGL(s);
1119 }
1120 }
1121 // draw path additional elements
1125}
1126
1127
1128void
1130 // check conditions
1132 const RGBColor currentLaneColor = laneColor.isValid() ? laneColor : setLaneColor(s);
1133 const RGBColor defaultMarkingColor = currentLaneColor.getContrastingColor();
1134 // check if this is the last lane (note: First lane is the lane more far of the edge's center)
1135 const bool firstlane = (myIndex == 0);
1136 const bool lastLane = (myIndex == (getParentEdges().front()->getNBEdge()->getNumLanes() - 1));
1137 // declare separator width
1138 const auto separatorWidth = SUMO_const_laneMarkWidth * 0.5;
1139 // get passengers change left and right for previous, current and next lane
1140 const bool changeRightTop = lastLane ? true : getParentEdges().front()->getNBEdge()->allowsChangingRight(myIndex + 1, SVC_PASSENGER);
1141 const bool changeLeftCurrent = lastLane ? true : getParentEdges().front()->getNBEdge()->allowsChangingLeft(myIndex, SVC_PASSENGER);
1142 const bool changeRightCurrent = firstlane ? true : getParentEdges().front()->getNBEdge()->allowsChangingRight(myIndex, SVC_PASSENGER);
1143 const bool changeLeftBot = firstlane ? true : getParentEdges().front()->getNBEdge()->allowsChangingLeft(myIndex - 1, SVC_PASSENGER);
1144 // save current color
1145 const auto currentColor = currentLaneColor;
1146 // separator offsets
1147 const double topSeparatorOffset = myDrawingConstants->getOffset() + (myDrawingConstants->getDrawingWidth() * -1) + separatorWidth;
1148 const double botSeparatorOffset = myDrawingConstants->getOffset() + myDrawingConstants->getDrawingWidth() - separatorWidth;
1149 // push matrix
1151 // translate
1152 glTranslated(0, 0, 0.1);
1153 // continue depending of lanes
1154 if (myDrawingConstants->drawSuperposed() || (firstlane && lastLane)) {
1155 // draw top and bot separator only
1156 GLHelper::setColor(defaultMarkingColor);
1157 GUIGeometry::drawGeometry(myDrawingConstants->getDetail(), myLaneGeometry, separatorWidth, topSeparatorOffset);
1158 GUIGeometry::drawGeometry(myDrawingConstants->getDetail(), myLaneGeometry, separatorWidth, botSeparatorOffset);
1159 } else if (firstlane) {
1160 // draw top separator
1161 GLHelper::setColor((changeLeftCurrent && changeRightTop) ? defaultMarkingColor : RGBColor::ORANGE);
1162 GUIGeometry::drawGeometry(myDrawingConstants->getDetail(), myLaneGeometry, separatorWidth, topSeparatorOffset);
1163 // check if draw inverse marking
1164 if (changeLeftCurrent) {
1165 GLHelper::setColor(currentColor);
1167 3, 6, topSeparatorOffset, true, true, s.lefthand, 1);
1168 }
1169 // draw bot separator
1170 GLHelper::setColor(defaultMarkingColor);
1171 GUIGeometry::drawGeometry(myDrawingConstants->getDetail(), myLaneGeometry, separatorWidth, botSeparatorOffset);
1172 } else if (lastLane) {
1173 // draw top separator
1174 GLHelper::setColor(defaultMarkingColor);
1175 GUIGeometry::drawGeometry(myDrawingConstants->getDetail(), myLaneGeometry, separatorWidth, topSeparatorOffset);
1176 // draw bot separator
1177 GLHelper::setColor((changeRightCurrent && changeLeftBot) ? defaultMarkingColor : RGBColor::ORANGE);
1178 GUIGeometry::drawGeometry(myDrawingConstants->getDetail(), myLaneGeometry, separatorWidth, botSeparatorOffset);
1179 // check if draw inverse marking
1180 if (changeRightCurrent) {
1181 GLHelper::setColor(currentColor);
1183 3, 6, botSeparatorOffset, true, true, s.lefthand, 1);
1184 }
1185 } else {
1186 // draw top separator
1187 GLHelper::setColor((changeLeftCurrent && changeRightTop) ? defaultMarkingColor : RGBColor::ORANGE);
1188 GUIGeometry::drawGeometry(myDrawingConstants->getDetail(), myLaneGeometry, separatorWidth, topSeparatorOffset);
1189 // check if draw inverse marking
1190 if (changeLeftCurrent) {
1191 GLHelper::setColor(currentColor);
1193 3, 6, topSeparatorOffset, true, true, s.lefthand, 1);
1194 }
1195 // draw bot separator
1196 GLHelper::setColor((changeRightCurrent && changeLeftBot) ? defaultMarkingColor : RGBColor::ORANGE);
1197 GUIGeometry::drawGeometry(myDrawingConstants->getDetail(), myLaneGeometry, separatorWidth, botSeparatorOffset);
1198 // check if draw inverse marking
1199 if (changeRightCurrent) {
1200 GLHelper::setColor(currentColor);
1202 3, 6, botSeparatorOffset, true, true, s.lefthand, 1);
1203 }
1204 }
1205 // pop matrix
1207 }
1208}
1209
1210
1211void
1213 // check draw conditions
1214 if (s.drawLinkJunctionIndex.show(getParentEdges().front()->getToJunction())) {
1215 // get connections
1216 const auto& connections = getParentEdges().front()->getNBEdge()->getConnectionsFromLane(myIndex);
1217 // get number of links
1218 const int noLinks = (int)connections.size();
1219 // only continue if there is links
1220 if (noLinks > 0) {
1221 // push link matrix
1223 // move front
1224 glTranslated(0, 0, GLO_TEXTNAME);
1225 // calculate width
1226 const double width = getParentEdges().front()->getNBEdge()->getLaneWidth(myIndex) / (double) noLinks;
1227 // get X1
1228 double x1 = getParentEdges().front()->getNBEdge()->getLaneWidth(myIndex) / 2;
1229 // iterate over links
1230 for (int i = noLinks - 1; i >= 0; i--) {
1231 // calculate x2
1232 const double x2 = x1 - (double)(width / 2.);
1233 // get link index
1234 const int linkIndex = getParentEdges().front()->getNBEdge()->getToNode()->getConnectionIndex(getParentEdges().front()->getNBEdge(),
1235 connections[s.lefthand ? noLinks - 1 - i : i]);
1236 // draw link index
1238 // update x1
1239 x1 -= width;
1240 }
1241 // pop link matrix
1243 }
1244 }
1245}
1246
1247
1248void
1250 // check conditions
1252 (getParentEdges().front()->getToJunction()->getNBNode()->getControllingTLS().size() > 0)) {
1253 // get connections
1254 const auto& connections = getParentEdges().front()->getNBEdge()->getConnectionsFromLane(myIndex);
1255 // get numer of links
1256 const int noLinks = (int)connections.size();
1257 // only continue if there are links
1258 if (noLinks > 0) {
1259 // push link matrix
1261 // move t front
1262 glTranslated(0, 0, GLO_TEXTNAME);
1263 // calculate width
1264 const double w = getParentEdges().front()->getNBEdge()->getLaneWidth(myIndex) / (double) noLinks;
1265 // calculate x1
1266 double x1 = getParentEdges().front()->getNBEdge()->getLaneWidth(myIndex) / 2;
1267 // iterate over links
1268 for (int i = noLinks - 1; i >= 0; --i) {
1269 // calculate x2
1270 const double x2 = x1 - (double)(w / 2.);
1271 // get link number
1272 const int linkNo = connections[s.lefthand ? noLinks - 1 - i : i].tlLinkIndex;
1273 // draw link number
1275 // update x1
1276 x1 -= w;
1277 }
1278 // pop link matrix
1280 }
1281 }
1282}
1283
1284
1285void
1286GNELane::drawArrows(const GUIVisualizationSettings& s, const RGBColor& laneColor) const {
1287 if (s.showLinkDecals && getParentEdges().front()->getToJunction()->isLogicValid()) {
1288 const RGBColor currentLaneColor = laneColor.isValid() ? laneColor : setLaneColor(s);
1289 // calculate begin, end and rotation
1290 const Position& begin = myLaneGeometry.getShape()[-2];
1291 const Position& end = myLaneGeometry.getShape().back();
1292 const double rot = GUIGeometry::calculateRotation(begin, end);
1293 // push arrow matrix
1295 // move front (note: must draw on top of junction shape?
1296 glTranslated(0, 0, 3);
1297 // change color depending of spreadSuperposed
1300 } else {
1301 GLHelper::setColor(currentLaneColor.getContrastingColor());
1302 }
1303 // move to end
1304 glTranslated(end.x(), end.y(), 0);
1305 // rotate
1306 glRotated(rot, 0, 0, 1);
1307 const double width = getParentEdges().front()->getNBEdge()->getLaneWidth(myIndex);
1308 if (width < SUMO_const_laneWidth) {
1310 }
1311 // apply offset
1312 glTranslated(myDrawingConstants->getOffset() * -1, 0, 0);
1313 // get destination node
1314 const NBNode* dest = getParentEdges().front()->getNBEdge()->myTo;
1315 // draw all links iterating over connections
1316 for (const auto& connection : getParentEdges().front()->getNBEdge()->myConnections) {
1317 if (connection.fromLane == myIndex) {
1318 // get link direction
1319 LinkDirection dir = dest->getDirection(getParentEdges().front()->getNBEdge(), connection.toEdge, s.lefthand);
1320 // draw depending of link direction
1321 switch (dir) {
1323 GLHelper::drawBoxLine(Position(0, 4), 0, 2, .05);
1324 GLHelper::drawTriangleAtEnd(Position(0, 4), Position(0, 1), (double) 1, (double) .25);
1325 break;
1327 GLHelper::drawBoxLine(Position(0, 4), 0, 1.5, .05);
1328 GLHelper::drawBoxLine(Position(0, 2.5), 90, 1, .05);
1329 GLHelper::drawTriangleAtEnd(Position(0, 2.5), Position(1.5, 2.5), (double) 1, (double) .25);
1330 break;
1332 GLHelper::drawBoxLine(Position(0, 4), 0, 1.5, .05);
1333 GLHelper::drawBoxLine(Position(0, 2.5), -90, 1, .05);
1334 GLHelper::drawTriangleAtEnd(Position(0, 2.5), Position(-1.5, 2.5), (double) 1, (double) .25);
1335 break;
1337 GLHelper::drawBoxLine(Position(0, 4), 0, 1.5, .05);
1338 GLHelper::drawBoxLine(Position(0, 2.5), 90, .5, .05);
1339 GLHelper::drawBoxLine(Position(0.5, 2.5), 180, 1, .05);
1340 GLHelper::drawTriangleAtEnd(Position(0.5, 2.5), Position(0.5, 4), (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::drawBoxLine(Position(-0.5, 2.5), -180, 1, .05);
1346 GLHelper::drawTriangleAtEnd(Position(-0.5, 2.5), Position(-0.5, 4), (double) 1, (double) .25);
1347 break;
1349 GLHelper::drawBoxLine(Position(0, 4), 0, 1.5, .05);
1350 GLHelper::drawBoxLine(Position(0, 2.5), 45, .7, .05);
1351 GLHelper::drawTriangleAtEnd(Position(0, 2.5), Position(1.2, 1.3), (double) 1, (double) .25);
1352 break;
1354 GLHelper::drawBoxLine(Position(0, 4), 0, 1.5, .05);
1355 GLHelper::drawBoxLine(Position(0, 2.5), -45, .7, .05);
1356 GLHelper::drawTriangleAtEnd(Position(0, 2.5), Position(-1.2, 1.3), (double) 1, (double) .25);
1357 break;
1359 GLHelper::drawBoxLine(Position(1, 5.8), 245, 2, .05);
1360 GLHelper::drawBoxLine(Position(-1, 5.8), 115, 2, .05);
1361 glTranslated(0, 5, 0);
1362 GLHelper::drawOutlineCircle(0.9, 0.8, 32);
1363 glTranslated(0, -5, 0);
1364 break;
1365 default:
1366 break;
1367 }
1368 }
1369 }
1370 // pop arrow matrix
1372 }
1373}
1374
1375
1376void
1379 glTranslated(0, 0, 0.1); // must draw on top of junction shape
1380 std::vector<NBEdge::Connection> connections = getParentEdges().front()->getNBEdge()->getConnectionsFromLane(myIndex);
1381 NBNode* node = getParentEdges().front()->getNBEdge()->getToNode();
1382 const Position& startPos = myLaneGeometry.getShape()[-1];
1383 for (auto it : connections) {
1384 const LinkState state = node->getLinkState(getParentEdges().front()->getNBEdge(), it.toEdge, it.fromLane, it.toLane, it.mayDefinitelyPass, it.tlID);
1385 switch (state) {
1387 glColor3d(1, 1, 0);
1388 break;
1390 glColor3d(0, 1, 1);
1391 break;
1392 case LINKSTATE_MAJOR:
1393 glColor3d(1, 1, 1);
1394 break;
1395 case LINKSTATE_MINOR:
1396 glColor3d(.4, .4, .4);
1397 break;
1398 case LINKSTATE_STOP:
1399 glColor3d(.7, .4, .4);
1400 break;
1401 case LINKSTATE_EQUAL:
1402 glColor3d(.7, .7, .7);
1403 break;
1405 glColor3d(.7, .7, 1);
1406 break;
1407 case LINKSTATE_ZIPPER:
1408 glColor3d(.75, .5, 0.25);
1409 break;
1410 default:
1411 throw ProcessError(TLF("Unexpected LinkState '%'", toString(state)));
1412 }
1413 const Position& endPos = it.toEdge->getLaneShape(it.toLane)[0];
1414 glBegin(GL_LINES);
1415 glVertex2d(startPos.x(), startPos.y());
1416 glVertex2d(endPos.x(), endPos.y());
1417 glEnd();
1418 GLHelper::drawTriangleAtEnd(startPos, endPos, (double) 1.5, (double) .2);
1419 }
1421}
1422
1423
1424void
1425GNELane::calculateLaneContour(const GUIVisualizationSettings& s, const double layer) const {
1426 // first check if edge parent was inserted with full boundary
1427 if (!gViewObjectsHandler.checkBoundaryParentObject(s, this, layer, getParentEdges().front())) {
1428 // calculate contour
1431 true, true, myDrawingConstants->getOffset(), nullptr, getParentEdges().front());
1432 // calculate geometry points contour if we're editing shape
1433 if (myShapeEdited) {
1437 }
1438 }
1439}
1440
1441
1444 const auto& inspectedElements = myNet->getViewNet()->getInspectedElements();
1445 // declare a RGBColor variable
1446 RGBColor color;
1447 // 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.
1448 if (inspectedElements.getFirstAC() &&
1449 !inspectedElements.getFirstAC()->isAttributeCarrierSelected() &&
1450 inspectedElements.getFirstAC()->getTagProperty()->vehicleEdges()) {
1451 // obtain attribute "via"
1452 std::vector<std::string> viaEdges = parse<std::vector<std::string> >(inspectedElements.getFirstAC()->getAttribute(SUMO_ATTR_VIA));
1453 // iterate over viaEdges
1454 for (const auto& edge : viaEdges) {
1455 // check if parent edge is in the via edges
1456 if (getParentEdges().front()->getID() == edge) {
1457 // set green color in GLHelper and return it
1458 color = RGBColor::GREEN;
1459 }
1460 }
1461 }
1462 if (mySpecialColor != nullptr) {
1463 // If special color is enabled, set it
1464 color = *mySpecialColor;
1465 } else if (getParentEdges().front()->drawUsingSelectColor() && s.laneColorer.getActive() != 1) {
1466 // override with special colors (unless the color scheme is based on selection)
1468 } else {
1469 // Get normal lane color
1470 const GUIColorer& c = s.laneColorer;
1471 if (!setFunctionalColor(c.getActive(), color) && !setMultiColor(s, c, color)) {
1472 color = c.getScheme().getColor(getColorValue(s, c.getActive()));
1473 }
1474 }
1475 // special color for conflicted candidate edges
1476 if (getParentEdges().front()->isConflictedCandidate()) {
1477 // extra check for route frame
1480 }
1481 }
1482 // special color for special candidate edges
1483 if (getParentEdges().front()->isSpecialCandidate()) {
1484 // extra check for route frame
1487 }
1488 }
1489 // special color for candidate edges
1490 if (getParentEdges().front()->isPossibleCandidate()) {
1491 // extra check for route frame
1494 }
1495 }
1496 // special color for source candidate edges
1497 if (getParentEdges().front()->isSourceCandidate()) {
1499 }
1500 // special color for target candidate edges
1501 if (getParentEdges().front()->isTargetCandidate()) {
1503 }
1504 // special color for invalid candidate edges
1505 if (getParentEdges().front()->isInvalidCandidate()) {
1507 }
1508 // special color for source candidate lanes
1509 if (mySourceCandidate) {
1511 }
1512 // special color for target candidate lanes
1513 if (myTargetCandidate) {
1515 }
1516 // special color for special candidate lanes
1517 if (mySpecialCandidate) {
1519 }
1520 // special color for possible candidate lanes
1521 if (myPossibleCandidate) {
1523 }
1524 // special color for conflicted candidate lanes
1527 }
1528 // special color for invalid candidate lanes
1529 if (myInvalidCandidate) {
1531 }
1532 // set color in GLHelper
1533 GLHelper::setColor(color);
1534 return color;
1535}
1536
1537
1538bool
1539GNELane::setFunctionalColor(int activeScheme, RGBColor& col) const {
1540 switch (activeScheme) {
1541 case 6: {
1542 double hue = GeomHelper::naviDegree(myLaneGeometry.getShape().beginEndAngle()); // [0-360]
1543 col = RGBColor::fromHSV(hue, 1., 1.);
1544 return true;
1545 }
1546 default:
1547 return false;
1548 }
1549}
1550
1551
1552bool
1554 const int activeScheme = c.getActive();
1555 myShapeColors.clear();
1556 switch (activeScheme) {
1557 case 9: // color by height at segment start
1558 for (PositionVector::const_iterator ii = myLaneGeometry.getShape().begin(); ii != myLaneGeometry.getShape().end() - 1; ++ii) {
1559 myShapeColors.push_back(c.getScheme().getColor(ii->z()));
1560 }
1561 col = c.getScheme().getColor(getColorValue(s, 8));
1562 return true;
1563 case 11: // color by inclination at segment start
1564 for (int ii = 1; ii < (int)myLaneGeometry.getShape().size(); ++ii) {
1565 const double inc = (myLaneGeometry.getShape()[ii].z() - myLaneGeometry.getShape()[ii - 1].z()) / MAX2(POSITION_EPS, myLaneGeometry.getShape()[ii].distanceTo2D(myLaneGeometry.getShape()[ii - 1]));
1566 myShapeColors.push_back(c.getScheme().getColor(inc));
1567 }
1568 col = c.getScheme().getColor(getColorValue(s, 10));
1569 return true;
1570 default:
1571 return false;
1572 }
1573}
1574
1575
1576double
1577GNELane::getColorValue(const GUIVisualizationSettings& s, int activeScheme) const {
1578 const SVCPermissions myPermissions = getParentEdges().front()->getNBEdge()->getPermissions(myIndex);
1579 if (mySpecialColor != nullptr && mySpecialColorValue != std::numeric_limits<double>::max()) {
1580 return mySpecialColorValue;
1581 }
1582 switch (activeScheme) {
1583 case 0:
1584 switch (myPermissions) {
1585 case SVC_PEDESTRIAN:
1586 return 1;
1587 case SVC_BICYCLE:
1588 return 2;
1589 case 0:
1590 // forbidden road or green verge
1591 return getParentEdges().front()->getNBEdge()->getPermissions() == 0 ? 10 : 3;
1592 case SVC_SHIP:
1593 return 4;
1594 case SVC_AUTHORITY:
1595 return 8;
1596 case SVC_AIRCRAFT:
1597 case SVC_DRONE:
1598 return 12;
1599 default:
1600 break;
1601 }
1602 if (getParentEdges().front()->getNBEdge()->isMacroscopicConnector()) {
1603 return 9;
1604 } else if (isRailway(myPermissions)) {
1605 return 5;
1606 } else if ((myPermissions & SVC_PASSENGER) != 0) {
1607 if ((myPermissions & (SVC_RAIL_CLASSES & ~SVC_RAIL_FAST)) != 0 && (myPermissions & SVC_SHIP) == 0) {
1608 return 6;
1609 } else {
1610 return 0;
1611 }
1612 } else {
1613 if ((myPermissions & SVC_RAIL_CLASSES) != 0 && (myPermissions & SVC_SHIP) == 0) {
1614 return 6;
1615 } else {
1616 return 7;
1617 }
1618 }
1619 case 1:
1620 return isAttributeCarrierSelected() || getParentEdges().front()->isAttributeCarrierSelected();
1621 case 2:
1622 return (double)myPermissions;
1623 case 3:
1624 return getParentEdges().front()->getNBEdge()->getLaneSpeed(myIndex);
1625 case 4:
1626 return getParentEdges().front()->getNBEdge()->getNumLanes();
1627 case 5: {
1628 return getParentEdges().front()->getNBEdge()->getLoadedLength() / getParentEdges().front()->getNBEdge()->getLaneStruct(myIndex).shape.length();
1629 }
1630 // case 6: by angle (functional)
1631 case 7: {
1632 return getParentEdges().front()->getNBEdge()->getPriority();
1633 }
1634 case 8: {
1635 // color by z of first shape point
1636 return myLaneGeometry.getShape()[0].z();
1637 }
1638 // case 9: by segment height
1639 case 10: {
1640 // color by incline
1641 return (myLaneGeometry.getShape()[-1].z() - myLaneGeometry.getShape()[0].z()) / getParentEdges().front()->getNBEdge()->getLength();
1642 }
1643 // case 11: by segment incline
1644
1645 case 12: {
1646 // by numerical edge param value
1647 if (getParentEdges().front()->getNBEdge()->hasParameter(s.edgeParam)) {
1648 try {
1649 return StringUtils::toDouble(getParentEdges().front()->getNBEdge()->getParameter(s.edgeParam, "0"));
1650 } catch (NumberFormatException&) {
1651 try {
1652 return StringUtils::toBool(getParentEdges().front()->getNBEdge()->getParameter(s.edgeParam, "0"));
1653 } catch (BoolFormatException&) {
1654 return -1;
1655 }
1656 }
1657 } else {
1659 }
1660 }
1661 case 13: {
1662 // by numerical lane param value
1663 if (getParentEdges().front()->getNBEdge()->getLaneStruct(myIndex).hasParameter(s.laneParam)) {
1664 try {
1665 return StringUtils::toDouble(getParentEdges().front()->getNBEdge()->getLaneStruct(myIndex).getParameter(s.laneParam, "0"));
1666 } catch (NumberFormatException&) {
1667 try {
1668 return StringUtils::toBool(getParentEdges().front()->getNBEdge()->getLaneStruct(myIndex).getParameter(s.laneParam, "0"));
1669 } catch (BoolFormatException&) {
1670 return -1;
1671 }
1672 }
1673 } else {
1675 }
1676 }
1677 case 14: {
1678 return getParentEdges().front()->getNBEdge()->getDistance();
1679 }
1680 case 15: {
1681 return fabs(getParentEdges().front()->getNBEdge()->getDistance());
1682 }
1683 }
1684 return 0;
1685}
1686
1687
1688void
1689GNELane::drawOverlappedRoutes(const int numRoutes) const {
1690 // get middle point and angle
1693 // Push route matrix
1695 // translate to front
1696 glTranslated(0, 0, GLO_ROUTE + 1);
1697 // get middle
1698 GLHelper::drawText(toString(numRoutes) + " routes", center, 0, 1.8, RGBColor::BLACK, angle + 90);
1699 // pop route matrix
1701
1702}
1703
1704
1705void
1707 const auto& laneStopOffset = getParentEdges().front()->getNBEdge()->getLaneStruct(myIndex).laneStopOffset;
1708 // check conditions
1709 if (laneStopOffset.isDefined() && (laneStopOffset.getPermissions() & SVC_PASSENGER) != 0) {
1710 const Position& end = getLaneShape().back();
1711 const Position& f = getLaneShape()[-2];
1712 const double rot = RAD2DEG(atan2((end.x() - f.x()), (f.y() - end.y())));
1715 glTranslated(end.x(), end.y(), 1);
1716 glRotated(rot, 0, 0, 1);
1717 glTranslated(0, laneStopOffset.getOffset(), 0);
1718 glBegin(GL_QUADS);
1719 glVertex2d(-myDrawingConstants->getDrawingWidth(), 0.0);
1720 glVertex2d(-myDrawingConstants->getDrawingWidth(), 0.2);
1721 glVertex2d(myDrawingConstants->getDrawingWidth(), 0.2);
1722 glVertex2d(myDrawingConstants->getDrawingWidth(), 0.0);
1723 glEnd();
1725 }
1726}
1727
1728
1729bool
1731 return isWaterway(getParentEdges().front()->getNBEdge()->getPermissions(myIndex)) && s.showRails; // reusing the showRails setting
1732}
1733
1734
1735void
1737 // Draw direction indicators if the correspondient option is enabled
1738 if (s.showLaneDirection) {
1739 // improve visibility of superposed rail edges
1741 glColor3d(0.3, 0.3, 0.3);
1742 }
1743 // get width and sideOffset
1744 const double width = MAX2(NUMERICAL_EPS, (myDrawingConstants->getDrawingWidth() * 2 * myDrawingConstants->getExaggeration()));
1745 // push direction indicator matrix
1747 // move to front
1748 glTranslated(0, 0, 0.1);
1749 // iterate over shape
1750 for (int i = 0; i < (int) myLaneGeometry.getShape().size() - 1; ++i) {
1751 // push triangle matrix
1753 // move front
1754 glTranslated(myLaneGeometry.getShape()[i].x(), myLaneGeometry.getShape()[i].y(), 0.1);
1755 // rotate
1756 glRotated(myLaneGeometry.getShapeRotations()[i], 0, 0, 1);
1757 // calculate subwidth
1758 for (double subWidth = 0; subWidth < myLaneGeometry.getShapeLengths()[i]; subWidth += width) {
1759 // calculate length
1760 const double length = MIN2(width * 0.5, myLaneGeometry.getShapeLengths()[i] - subWidth);
1761 // draw triangle
1762 glBegin(GL_TRIANGLES);
1763 glVertex2d(-myDrawingConstants->getOffset(), -subWidth - length);
1764 glVertex2d(-myDrawingConstants->getOffset() - width * 0.25, -subWidth);
1765 glVertex2d(-myDrawingConstants->getOffset() + width * 0.25, -subWidth);
1766 glEnd();
1767 }
1768 // pop triangle matrix
1770 }
1771 // pop direction indicator matrix
1773 }
1774}
1775
1776
1777void
1779 // draw foot width 150mm, assume that distance between rail feet inner sides is reduced on both sides by 39mm with regard to the gauge
1780 // assume crosstie length of 181% gauge (2600mm for standard gauge)
1781 // first save current color (obtained from view configuration)
1782 const auto currentLaneColor = GLHelper::getColor();
1783 // Set current color
1784 GLHelper::setColor(currentLaneColor);
1785 // continue depending of detail
1787 // move
1788 glTranslated(0, 0, 0.1);
1789 // draw external crossbar
1790 const double crossbarWidth = 0.2 * myDrawingConstants->getExaggeration();
1791 // draw geometry
1795 // move
1796 glTranslated(0, 0, 0.01);
1797 // Set color gray
1798 glColor3d(0.8, 0.8, 0.8);
1799 // draw geometry
1803 // move
1804 glTranslated(0, 0, 0.01);
1805 // Set current color
1806 GLHelper::setColor(currentLaneColor);
1807 // Draw crossties
1810 myDrawingConstants->getOffset(), false);
1811 } else if (myShapeColors.size() > 0) {
1812 // draw colored box lines
1815 } else {
1816 // draw geometry with current color
1819 }
1820}
1821
1822
1823void
1825 // check all conditions for drawing textures
1826 if (!s.disableLaneIcons && (myLaneRestrictedTexturePositions.size() > 0)) {
1827 // Declare default width of icon (3)
1828 const double iconWidth = myDrawingConstants->getDrawingWidth() * 0.6;
1829 // Draw list of icons
1830 for (int i = 0; i < (int)myLaneRestrictedTexturePositions.size(); i++) {
1831 // Push draw matrix 2
1833 // Set white color
1834 glColor3d(1, 1, 1);
1835 // Translate matrix 2
1836 glTranslated(myLaneRestrictedTexturePositions.at(i).x(), myLaneRestrictedTexturePositions.at(i).y(), 0.1);
1837 // Rotate matrix 2
1838 glRotated(myLaneRestrictedTextureRotations.at(i), 0, 0, -1);
1839 glRotated(90, 0, 0, 1);
1840 // draw texture box depending of type of restriction
1843 } else if (isRestricted(SVC_BICYCLE)) {
1845 } else if (isRestricted(SVC_BUS)) {
1847 }
1848 // Pop draw matrix 2
1850 }
1851 }
1852}
1853
1854
1855void
1857 // draw a Start/endPoints if lane has a custom shape
1858 if ((myDrawingConstants->getDetail() <= GUIVisualizationSettings::Detail::GeometryPoint) && (getParentEdges().front()->getNBEdge()->getLaneStruct(myIndex).customShape.size() > 1)) {
1859 // obtain circle width and resolution
1860 const double circleWidth = GNEEdge::SNAP_RADIUS * MIN2((double)1, s.laneWidthExaggeration) / 2;
1861 // obtain custom shape
1862 const PositionVector& customShape = getParentEdges().front()->getNBEdge()->getLaneStruct(myIndex).customShape;
1863 // set color (override with special colors unless the color scheme is based on selection)
1864 if (drawUsingSelectColor() && s.laneColorer.getActive() != 1) {
1866 } else {
1867 GLHelper::setColor(s.junctionColorer.getSchemes()[0].getColor(2));
1868 }
1869 // push start matrix
1871 // move to shape start position
1872 glTranslated(customShape.front().x(), customShape.front().y(), 0.1);
1873 // draw circle
1875 // draw s depending of detail
1877 // move top
1878 glTranslated(0, 0, 0.1);
1879 // draw "S"
1880 GLHelper::drawText("S", Position(), 0.1, circleWidth, RGBColor::WHITE);
1881 }
1882 // pop start matrix
1884 // draw line between junction and start position
1886 // move top
1887 glTranslated(0, 0, 0.1);
1888 // set line width
1889 glLineWidth(4);
1890 // draw line
1891 GLHelper::drawLine(customShape.front(), getParentEdges().front()->getFromJunction()->getPositionInView());
1892 // pop line matrix
1894 // push start matrix
1896 // move to end position
1897 glTranslated(customShape.back().x(), customShape.back().y(), 0.1);
1898 // draw filled circle
1900 // draw "e" depending of detail
1902 // move top
1903 glTranslated(0, 0, 0.1);
1904 // draw "E"
1905 GLHelper::drawText("E", Position(), 0, circleWidth, RGBColor::WHITE);
1906 }
1907 // pop start matrix
1909 // draw line between Junction and end position
1911 // move top
1912 glTranslated(0, 0, 0.1);
1913 // set line width
1914 glLineWidth(4);
1915 // draw line
1916 GLHelper::drawLine(customShape.back(), getParentEdges().front()->getToJunction()->getPositionInView());
1917 // pop line matrix
1919 }
1920}
1921
1922
1923bool
1925 return setLaneColor(s).alpha() != 0;
1926}
1927
1928
1929std::string
1931 return getParentEdges().front()->getID();
1932}
1933
1934
1935long
1936GNELane::onDefault(FXObject* obj, FXSelector sel, void* data) {
1937 myNet->getViewParent()->getTLSEditorFrame()->handleMultiChange(this, obj, sel, data);
1938 return 1;
1939}
1940
1941
1942std::vector<GNEConnection*>
1944 // Declare a vector to save incoming connections
1945 std::vector<GNEConnection*> incomingConnections;
1946 // Obtain incoming edges if junction source was already created
1947 GNEJunction* junctionSource = getParentEdges().front()->getFromJunction();
1948 if (junctionSource) {
1949 // Iterate over incoming GNEEdges of junction
1950 for (const auto& incomingEdge : junctionSource->getGNEIncomingEdges()) {
1951 // Iterate over connection of incoming edges
1952 for (const auto& connection : incomingEdge->getGNEConnections()) {
1953 if (connection->getLaneTo()->getIndex() == getIndex()) {
1954 incomingConnections.push_back(connection);
1955 }
1956 }
1957 }
1958 }
1959 return incomingConnections;
1960}
1961
1962
1963std::vector<GNEConnection*>
1965 // Obtain GNEConnection of parent edge
1966 const std::vector<GNEConnection*>& edgeConnections = getParentEdges().front()->getGNEConnections();
1967 std::vector<GNEConnection*> outcomingConnections;
1968 // Obtain outgoing connections
1969 for (const auto& connection : edgeConnections) {
1970 if (connection->getLaneFrom()->getIndex() == getIndex()) {
1971 outcomingConnections.push_back(connection);
1972 }
1973 }
1974 return outcomingConnections;
1975}
1976
1977
1978void
1980 // update incoming connections of lane
1981 std::vector<GNEConnection*> incomingConnections = getGNEIncomingConnections();
1982 for (const auto& incomingConnection : incomingConnections) {
1983 incomingConnection->updateConnectionID();
1984 }
1985 // update outcoming connections of lane
1986 std::vector<GNEConnection*> outcomingConnections = getGNEOutcomingConnections();
1987 for (const auto& outcomingConnection : outcomingConnections) {
1988 outcomingConnection->updateConnectionID();
1989 }
1990}
1991
1992
1993double
1995 // factor should not be 0
1996 if (getParentEdges().front()->getNBEdge()->getFinalLength() > 0) {
1997 return MAX2(POSITION_EPS, (getLaneShape().length() / getParentEdges().front()->getNBEdge()->getFinalLength()));
1998 } else {
1999 return POSITION_EPS;
2000 };
2001}
2002
2003
2004void
2006 // Create basic commands
2007 std::string edgeDescPossibleMulti = toString(SUMO_TAG_EDGE);
2008 const int edgeSelSize = getParentEdges().front()->isAttributeCarrierSelected() ? myNet->getAttributeCarriers()->getNumberOfSelectedEdges() : 0;
2009 if (edgeSelSize && getParentEdges().front()->isAttributeCarrierSelected() && (edgeSelSize > 1)) {
2010 edgeDescPossibleMulti = toString(edgeSelSize) + " " + toString(SUMO_TAG_EDGE) + "s";
2011 }
2012 // create menu pane for edge operations
2013 FXMenuPane* edgeOperations = new FXMenuPane(ret);
2014 ret->insertMenuPaneChild(edgeOperations);
2015 if (edgeSelSize > 0) {
2016 new FXMenuCascade(ret, TLF("Edge operations (% selected)", toString(edgeSelSize)).c_str(), nullptr, edgeOperations);
2017 } else {
2018 new FXMenuCascade(ret, TL("Edge operations"), nullptr, edgeOperations);
2019 }
2020 // create menu commands for all edge operations
2021 GUIDesigns::buildFXMenuCommand(edgeOperations, TL("Split edge here"), nullptr, &parent, MID_GNE_EDGE_SPLIT);
2022 auto splitBothDirections = GUIDesigns::buildFXMenuCommand(edgeOperations, TL("Split edge in both directions here (no symmetric opposite edge)"), nullptr, &parent, MID_GNE_EDGE_SPLIT_BIDI);
2023 // check if allow split edge in both directions
2024 splitBothDirections->disable();
2025 const auto oppositeEdges = getParentEdges().front()->getOppositeEdges();
2026 if (oppositeEdges.size() == 0) {
2027 splitBothDirections->setText(TL("Split edge in both directions here (no opposite edge)"));
2028 } else {
2029 for (const auto& oppositeEdge : oppositeEdges) {
2030 // get reverse inner geometry
2031 const auto reverseGeometry = oppositeEdge->getNBEdge()->getInnerGeometry().reverse();
2032 if (reverseGeometry == getParentEdges().front()->getNBEdge()->getInnerGeometry()) {
2033 splitBothDirections->enable();
2034 splitBothDirections->setText(TL("Split edge in both directions here"));
2035 }
2036 }
2037 }
2038 GUIDesigns::buildFXMenuCommand(edgeOperations, TL("Set geometry endpoint here (shift-click)"), nullptr, &parent, MID_GNE_EDGE_EDIT_ENDPOINT);
2039 // restore geometry points depending of selection status
2040 if (getParentEdges().front()->isAttributeCarrierSelected()) {
2041 if (edgeSelSize == 1) {
2042 GUIDesigns::buildFXMenuCommand(edgeOperations, TL("Restore both geometry endpoints"), nullptr, &parent, MID_GNE_EDGE_RESET_ENDPOINT);
2043 } else {
2044 GUIDesigns::buildFXMenuCommand(edgeOperations, TL("Restore geometry endpoints of all selected edges"), nullptr, &parent, MID_GNE_EDGE_RESET_ENDPOINT);
2045 }
2046 } else {
2047 GUIDesigns::buildFXMenuCommand(edgeOperations, TL("Restore geometry endpoint (shift-click)"), nullptr, &parent, MID_GNE_EDGE_RESET_ENDPOINT);
2048 }
2049 GUIDesigns::buildFXMenuCommand(edgeOperations, TLF("Reverse %", edgeDescPossibleMulti), nullptr, &parent, MID_GNE_EDGE_REVERSE);
2050 auto reverse = GUIDesigns::buildFXMenuCommand(edgeOperations, TLF("Add reverse direction for %", edgeDescPossibleMulti), nullptr, &parent, MID_GNE_EDGE_ADD_REVERSE);
2051 if (getParentEdges().front()->getReverseEdge() != nullptr) {
2052 reverse->disable();
2053 }
2054 GUIDesigns::buildFXMenuCommand(edgeOperations, TLF("Add reverse disconnected direction for %", edgeDescPossibleMulti), nullptr, &parent, MID_GNE_EDGE_ADD_REVERSE_DISCONNECTED);
2055 GUIDesigns::buildFXMenuCommand(edgeOperations, TLF("Reset lengths for %", edgeDescPossibleMulti), nullptr, &parent, MID_GNE_EDGE_RESET_LENGTH);
2056 GUIDesigns::buildFXMenuCommand(edgeOperations, TLF("Straighten %", edgeDescPossibleMulti), nullptr, &parent, MID_GNE_EDGE_STRAIGHTEN);
2057 GUIDesigns::buildFXMenuCommand(edgeOperations, TLF("Smooth %", edgeDescPossibleMulti), nullptr, &parent, MID_GNE_EDGE_SMOOTH);
2058 GUIDesigns::buildFXMenuCommand(edgeOperations, TLF("Straighten elevation of %", edgeDescPossibleMulti), nullptr, &parent, MID_GNE_EDGE_STRAIGHTEN_ELEVATION);
2059 GUIDesigns::buildFXMenuCommand(edgeOperations, TLF("Smooth elevation of %", edgeDescPossibleMulti), nullptr, &parent, MID_GNE_EDGE_SMOOTH_ELEVATION);
2060}
2061
2062
2063void
2065 // Get icons
2066 FXIcon* pedestrianIcon = GUIIconSubSys::getIcon(GUIIcon::LANE_PEDESTRIAN);
2067 FXIcon* bikeIcon = GUIIconSubSys::getIcon(GUIIcon::LANE_BIKE);
2068 FXIcon* busIcon = GUIIconSubSys::getIcon(GUIIcon::LANE_BUS);
2069 FXIcon* greenVergeIcon = GUIIconSubSys::getIcon(GUIIcon::LANEGREENVERGE);
2070 // declare number of selected lanes
2071 int numSelectedLanes = 0;
2072 // if lane is selected, calculate number of restricted lanes
2073 bool edgeHasSidewalk = false;
2074 bool edgeHasBikelane = false;
2075 bool edgeHasBuslane = false;
2076 bool differentLaneShapes = false;
2078 const auto selectedLanes = myNet->getAttributeCarriers()->getSelectedLanes();
2079 // update numSelectedLanes
2080 numSelectedLanes = (int)selectedLanes.size();
2081 // iterate over selected lanes
2082 for (const auto& selectedLane : selectedLanes) {
2083 if (selectedLane->getParentEdges().front()->hasRestrictedLane(SVC_PEDESTRIAN)) {
2084 edgeHasSidewalk = true;
2085 }
2086 if (selectedLane->getParentEdges().front()->hasRestrictedLane(SVC_BICYCLE)) {
2087 edgeHasBikelane = true;
2088 }
2089 if (selectedLane->getParentEdges().front()->hasRestrictedLane(SVC_BUS)) {
2090 edgeHasBuslane = true;
2091 }
2092 if (selectedLane->getParentEdges().front()->getNBEdge()->getLaneStruct(selectedLane->getIndex()).customShape.size() != 0) {
2093 differentLaneShapes = true;
2094 }
2095 }
2096 } else {
2097 edgeHasSidewalk = getParentEdges().front()->hasRestrictedLane(SVC_PEDESTRIAN);
2098 edgeHasBikelane = getParentEdges().front()->hasRestrictedLane(SVC_BICYCLE);
2099 edgeHasBuslane = getParentEdges().front()->hasRestrictedLane(SVC_BUS);
2100 differentLaneShapes = getParentEdges().front()->getNBEdge()->getLaneStruct(myIndex).customShape.size() != 0;
2101 }
2102 // create menu pane for lane operations
2103 FXMenuPane* laneOperations = new FXMenuPane(ret);
2104 ret->insertMenuPaneChild(laneOperations);
2105 if (numSelectedLanes > 0) {
2106 new FXMenuCascade(ret, TLF("Lane operations (% selected)", toString(numSelectedLanes)).c_str(), nullptr, laneOperations);
2107 } else {
2108 new FXMenuCascade(ret, TL("Lane operations"), nullptr, laneOperations);
2109 }
2110 GUIDesigns::buildFXMenuCommand(laneOperations, TL("Duplicate lane"), nullptr, &parent, MID_GNE_LANE_DUPLICATE);
2111 GUIDesigns::buildFXMenuCommand(laneOperations, TL("Set custom lane shape"), nullptr, &parent, MID_GNE_LANE_EDIT_SHAPE);
2112 FXMenuCommand* resetCustomShape = GUIDesigns::buildFXMenuCommand(laneOperations, TL("Reset custom shape"), nullptr, &parent, MID_GNE_LANE_RESET_CUSTOMSHAPE);
2113 if (!differentLaneShapes) {
2114 resetCustomShape->disable();
2115 }
2116 FXMenuCommand* resetOppositeLane = GUIDesigns::buildFXMenuCommand(laneOperations, TL("Reset opposite lane"), nullptr, &parent, MID_GNE_LANE_RESET_OPPOSITELANE);
2117 if (getAttribute(GNE_ATTR_OPPOSITE).empty()) {
2118 resetOppositeLane->disable();
2119 }
2120 // Create panel for lane operations and insert it in ret
2121 FXMenuPane* addSpecialLanes = new FXMenuPane(laneOperations);
2122 ret->insertMenuPaneChild(addSpecialLanes);
2123 FXMenuPane* removeSpecialLanes = new FXMenuPane(laneOperations);
2124 ret->insertMenuPaneChild(removeSpecialLanes);
2125 FXMenuPane* transformSlanes = new FXMenuPane(laneOperations);
2126 ret->insertMenuPaneChild(transformSlanes);
2127 // Create menu comands for all add special lanes
2128 FXMenuCommand* addSidewalk = GUIDesigns::buildFXMenuCommand(addSpecialLanes, TL("Sidewalk"), pedestrianIcon, &parent, MID_GNE_LANE_ADD_SIDEWALK);
2129 FXMenuCommand* addBikelane = GUIDesigns::buildFXMenuCommand(addSpecialLanes, TL("Bike lane"), bikeIcon, &parent, MID_GNE_LANE_ADD_BIKE);
2130 FXMenuCommand* addBuslane = GUIDesigns::buildFXMenuCommand(addSpecialLanes, TL("Bus lane"), busIcon, &parent, MID_GNE_LANE_ADD_BUS);
2131 // if parent edge is selected, always add greenverge in front
2132 if (getParentEdges().front()->isAttributeCarrierSelected()) {
2133 GUIDesigns::buildFXMenuCommand(addSpecialLanes, TL("Green verge"), greenVergeIcon, &parent, MID_GNE_LANE_ADD_GREENVERGE_FRONT);
2134 } else {
2135 GUIDesigns::buildFXMenuCommand(addSpecialLanes, TL("Green verge (front)"), greenVergeIcon, &parent, MID_GNE_LANE_ADD_GREENVERGE_FRONT);
2136 GUIDesigns::buildFXMenuCommand(addSpecialLanes, TL("Green verge (back)"), greenVergeIcon, &parent, MID_GNE_LANE_ADD_GREENVERGE_BACK);
2137 }
2138 // Create menu comands for all remove special lanes and disable it
2139 FXMenuCommand* removeSidewalk = GUIDesigns::buildFXMenuCommand(removeSpecialLanes, TL("Sidewalk"), pedestrianIcon, &parent, MID_GNE_LANE_REMOVE_SIDEWALK);
2140 removeSidewalk->disable();
2141 FXMenuCommand* removeBikelane = GUIDesigns::buildFXMenuCommand(removeSpecialLanes, TL("Bike lane"), bikeIcon, &parent, MID_GNE_LANE_REMOVE_BIKE);
2142 removeBikelane->disable();
2143 FXMenuCommand* removeBuslane = GUIDesigns::buildFXMenuCommand(removeSpecialLanes, TL("Bus lane"), busIcon, &parent, MID_GNE_LANE_REMOVE_BUS);
2144 removeBuslane->disable();
2145 FXMenuCommand* removeGreenVerge = GUIDesigns::buildFXMenuCommand(removeSpecialLanes, TL("Green verge"), greenVergeIcon, &parent, MID_GNE_LANE_REMOVE_GREENVERGE);
2146 removeGreenVerge->disable();
2147 // Create menu comands for all transform special lanes and disable it
2148 FXMenuCommand* transformLaneToSidewalk = GUIDesigns::buildFXMenuCommand(transformSlanes, TL("Sidewalk"), pedestrianIcon, &parent, MID_GNE_LANE_TRANSFORM_SIDEWALK);
2149 FXMenuCommand* transformLaneToBikelane = GUIDesigns::buildFXMenuCommand(transformSlanes, TL("Bike lane"), bikeIcon, &parent, MID_GNE_LANE_TRANSFORM_BIKE);
2150 FXMenuCommand* transformLaneToBuslane = GUIDesigns::buildFXMenuCommand(transformSlanes, TL("Bus lane"), busIcon, &parent, MID_GNE_LANE_TRANSFORM_BUS);
2151 FXMenuCommand* transformLaneToGreenVerge = GUIDesigns::buildFXMenuCommand(transformSlanes, TL("Green verge"), greenVergeIcon, &parent, MID_GNE_LANE_TRANSFORM_GREENVERGE);
2152 // add menuCascade for lane operations
2153 new FXMenuCascade(laneOperations, TLF("Add restricted %", toString(SUMO_TAG_LANE)).c_str(), nullptr, addSpecialLanes);
2154 FXMenuCascade* cascadeRemoveSpecialLane = new FXMenuCascade(laneOperations, TLF("Remove restricted %", toString(SUMO_TAG_LANE)).c_str(), nullptr, removeSpecialLanes);
2155 new FXMenuCascade(laneOperations, TLF("Transform to restricted %", toString(SUMO_TAG_LANE)).c_str(), nullptr, transformSlanes);
2156 // Enable and disable options depending of current transform of the lane
2157 if (edgeHasSidewalk) {
2158 transformLaneToSidewalk->disable();
2159 addSidewalk->disable();
2160 removeSidewalk->enable();
2161 }
2162 if (edgeHasBikelane) {
2163 transformLaneToBikelane->disable();
2164 addBikelane->disable();
2165 removeBikelane->enable();
2166 }
2167 if (edgeHasBuslane) {
2168 transformLaneToBuslane->disable();
2169 addBuslane->disable();
2170 removeBuslane->enable();
2171 }
2173 transformLaneToGreenVerge->disable();
2174 removeGreenVerge->enable();
2175 }
2176 // Check if cascade menu must be disabled
2177 if (!edgeHasSidewalk && !edgeHasBikelane && !edgeHasBuslane && !isRestricted(SVC_IGNORING)) {
2178 cascadeRemoveSpecialLane->disable();
2179 }
2180 // for whatever reason, sonar complains in the next line that cascadeRemoveSpecialLane may leak, but fox does the cleanup
2181} // NOSONAR
2182
2183
2184void
2186 // Create basic commands
2187 std::string edgeDescPossibleMulti = toString(SUMO_TAG_EDGE);
2188 const int numSelectedEdges = getParentEdges().front()->isAttributeCarrierSelected() ? myNet->getAttributeCarriers()->getNumberOfSelectedEdges() : 0;
2189 if ((numSelectedEdges > 0) && getParentEdges().front()->isAttributeCarrierSelected() && (numSelectedEdges > 1)) {
2190 edgeDescPossibleMulti = toString(numSelectedEdges) + " " + toString(SUMO_TAG_EDGE) + "s";
2191 }
2192 // create menu pane for edge operations
2193 FXMenuPane* edgeOperations = new FXMenuPane(ret);
2194 ret->insertMenuPaneChild(edgeOperations);
2195 if (numSelectedEdges > 0) {
2196 new FXMenuCascade(ret, TLF("Template operations (% selected)", toString(numSelectedEdges)).c_str(), nullptr, edgeOperations);
2197 } else {
2198 new FXMenuCascade(ret, TL("Template operations"), nullptr, edgeOperations);
2199 }
2200 // create menu commands for all edge operations
2201 GUIDesigns::buildFXMenuCommand(edgeOperations, TL("Use edge as template"), nullptr, &parent, MID_GNE_EDGE_USEASTEMPLATE);
2202 auto applyTemplate = GUIDesigns::buildFXMenuCommand(edgeOperations, TL("Apply template"), nullptr, &parent, MID_GNE_EDGE_APPLYTEMPLATE);
2203 // check if disable apply template
2205 applyTemplate->disable();
2206 }
2207}
2208
2209
2210void
2212 // addreachability menu
2213 FXMenuPane* reachableByClass = new FXMenuPane(ret);
2214 ret->insertMenuPaneChild(reachableByClass);
2215 if (myNet->isNetRecomputed()) {
2216 new FXMenuCascade(ret, TL("Select reachable"), GUIIconSubSys::getIcon(GUIIcon::MODEVEHICLE), reachableByClass);
2217 for (const auto& vClass : SumoVehicleClassStrings.getStrings()) {
2218 GUIDesigns::buildFXMenuCommand(reachableByClass, vClass.c_str(), VClassIcons::getVClassIcon(SumoVehicleClassStrings.get(vClass)), &parent, MID_REACHABILITY);
2219 }
2220 } else {
2221 FXMenuCommand* menuCommand = GUIDesigns::buildFXMenuCommand(ret, TL("Select reachable (compute junctions)"), nullptr, nullptr, 0);
2222 menuCommand->handle(&parent, FXSEL(SEL_COMMAND, FXWindow::ID_DISABLE), nullptr);
2223 }
2224}
2225
2226/****************************************************************************/
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:871
@ 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:493
@ MID_GNE_LANE_ADD_BUS
add busLane
@ MID_GNE_REMOVESELECT_EDGE
Remove edge from selected items - Menu Entry.
Definition GUIAppEnum.h:873
@ 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_SHOWPARS_PARENT
Show object parent parameter - popup entry.
Definition GUIAppEnum.h:479
@ MID_COPY_EDGE_NAME
Copy edge name (for lanes only)
Definition GUIAppEnum.h:465
@ 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:541
@ 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_SHOWPARS
Show object parameter - popup entry.
Definition GUIAppEnum.h:477
@ 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_DELETE
delete item - menu entry
Definition GUIAppEnum.h:497
@ 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:495
@ 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:287
#define TL(string)
Definition MsgHandler.h:304
#define TLF(string,...)
Definition MsgHandler.h:306
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_ACCESS
An access point for a train stop.
@ 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:49
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 drawFilledCircleDetailed(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 drawBoxLine(const Position &beg, double rot, double visLength, double width, double offset=0)
Draws a thick line.
Definition GLHelper.cpp:296
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
GNETagSelector * getAdditionalTagSelector() const
get additional tag selector
bool isAttributeCarrierSelected() const
check if attribute carrier is selected
double getCommonAttributeDouble(SumoXMLAttr key) const
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)
const std::string getID() const override
get ID (all Attribute Carriers have one)
PositionVector getCommonAttributePositionVector(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
Position getCommonAttributePosition(SumoXMLAttr key) const
GNENet * myNet
pointer to net
GNENet * getNet() const
get pointer to net
bool isCommonAttributeValid(SumoXMLAttr key, const std::string &value) const
std::string getCommonAttribute(SumoXMLAttr key) const
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
NBEdge * getNBEdge() const
returns the internal NBEdge
Definition GNEEdge.cpp:773
static const double SNAP_RADIUS
Definition GNEEdge.h:321
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:68
GUIVisualizationSettings::Detail myDetail
detail level
Definition GNELane.h:99
bool drawAsRailway() const
draw as railway
Definition GNELane.cpp:142
bool drawSuperposed() const
draw superposed
Definition GNELane.cpp:148
double getExaggeration() const
get exaggeration
Definition GNELane.cpp:112
double myExaggeration
exaggeration
Definition GNELane.h:87
double getDrawingWidth() const
get lane drawing width
Definition GNELane.cpp:118
double getInternalDrawingWidth() const
get internal lane drawing width
Definition GNELane.cpp:124
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:130
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:136
GNELane2laneConnection myLane2laneConnections
lane2lane connections
Definition GNELane.h:387
const PositionVector & getLaneShape() const
get elements shape
Definition GNELane.cpp:234
bool isAttributeComputed(SumoXMLAttr key) const override
Definition GNELane.cpp:891
const GNELane2laneConnection & getLane2laneConnections() const
get Lane2laneConnection struct
Definition GNELane.cpp:683
~GNELane()
Destructor.
Definition GNELane.cpp:190
double getColorValue(const GUIVisualizationSettings &s, int activeScheme) const override
return value for lane coloring according to the given scheme
Definition GNELane.cpp:1577
void drawLaneStopOffset(const GUIVisualizationSettings &s) const
draw laneStopOffset
Definition GNELane.cpp:1706
void drawSelectedLane(const GUIVisualizationSettings &s) const
draw selected lane
Definition GNELane.cpp:1063
std::vector< double > myLaneRestrictedTextureRotations
Rotations of textures of restricted lanes.
Definition GNELane.h:374
bool allowPedestrians() const
check if current lane allow pedestrians
Definition GNELane.cpp:222
bool checkDrawSelectContour() const override
check if draw select contour (blue)
Definition GNELane.cpp:431
const RGBColor * mySpecialColor
optional special color
Definition GNELane.h:378
Position getPositionInView() const
Returns position of hierarchical element in view.
Definition GNELane.cpp:340
bool drawAsWaterway(const GUIVisualizationSettings &s) const
whether to draw this lane as a waterways
Definition GNELane.cpp:1730
Boundary getCenteringBoundary() const override
Returns the boundary to which the view shall be centered in order to show the object.
Definition GNELane.cpp:629
double getLengthGeometryFactor() const
get length geometry factor
Definition GNELane.cpp:1994
PositionVector getAttributePositionVector(SumoXMLAttr key) const override
Definition GNELane.cpp:758
void drawDirectionIndicators(const GUIVisualizationSettings &s) const
direction indicators for lanes
Definition GNELane.cpp:1736
bool checkDrawOverContour() const override
check if draw over contour (orange)
Definition GNELane.cpp:387
int getIndex() const
returns the index of the lane
Definition GNELane.cpp:641
GNEMoveElementLane * myMoveElementLane
move element lane
Definition GNELane.h:356
GUIGeometry myLaneGeometry
lane geometry
Definition GNELane.h:362
void drawShapeEdited(const GUIVisualizationSettings &s) const
draw shape edited
Definition GNELane.cpp:1082
void drawOverlappedRoutes(const int numRoutes) const
draw overlapped routes
Definition GNELane.cpp:1689
bool checkDrawRelatedContour() const override
check if draw related contour (cyan)
Definition GNELane.cpp:372
GUIGLObjectPopupMenu * getPopUpMenu(GUIMainWindow &app, GUISUMOAbstractView &parent) override
Returns an own popup-menu.
Definition GNELane.cpp:504
bool checkDrawToContour() const override
check if draw from contour (magenta)
Definition GNELane.cpp:359
std::string getParentName() const override
Returns the name of the parent object (if any)
Definition GNELane.cpp:1930
void buildLaneOperations(GUISUMOAbstractView &parent, GUIGLObjectPopupMenu *ret)
build lane operations contextual menu
Definition GNELane.cpp:2064
GNEMoveElement * getMoveElement() const override
methods to retrieve the elements linked to this lane
Definition GNELane.cpp:198
GNELane()
FOX needs this.
Definition GNELane.cpp:177
std::vector< GNEConnection * > getGNEOutcomingConnections()
returns a vector with the outgoing GNEConnections of this lane
Definition GNELane.cpp:1964
DrawingConstants * myDrawingConstants
LaneDrawingConstants.
Definition GNELane.h:365
const std::vector< double > & getShapeRotations() const
get rotations of the single shape parts
Definition GNELane.cpp:244
std::string getAttributeForSelection(SumoXMLAttr key) const override
method for getting the attribute in the context of object selection
Definition GNELane.cpp:770
void buildTemplateOperations(GUISUMOAbstractView &parent, GUIGLObjectPopupMenu *ret)
build template oerations contextual menu
Definition GNELane.cpp:2185
double getExaggeration(const GUIVisualizationSettings &s) const override
return exaggeration associated with this GLObject
Definition GNELane.cpp:623
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:1553
void drawMarkingsAndBoundings(const GUIVisualizationSettings &s, const RGBColor &laneColor=RGBColor(false)) const
draw lane markings
Definition GNELane.cpp:1129
void calculateLaneContour(const GUIVisualizationSettings &s, const double layer) const
calculate contour
Definition GNELane.cpp:1425
void drawTLSLinkNo(const GUIVisualizationSettings &s) const
draw TLS link Number
Definition GNELane.cpp:1249
double getLaneParametricLength() const
returns the parameteric length of the lane
Definition GNELane.cpp:660
RGBColor setLaneColor(const GUIVisualizationSettings &s) const
set color according to edit mode and visualisation settings
Definition GNELane.cpp:1443
std::vector< GNEConnection * > getGNEIncomingConnections()
returns a vector with the incoming GNEConnections of this lane
Definition GNELane.cpp:1943
void updateGeometry() override
update pre-computed geometry information
Definition GNELane.cpp:262
bool isRestricted(SUMOVehicleClass vclass) const
check if this lane is restricted
Definition GNELane.cpp:677
bool checkDrawFromContour() const override
check if draw from contour (green)
Definition GNELane.cpp:346
const DrawingConstants * getDrawingConstants() const
get lane drawing constants (previously calculated in drawGL())
Definition GNELane.cpp:256
int myIndex
The index of this lane.
Definition GNELane.h:359
void drawLaneAsRailway() const
draw lane as railway
Definition GNELane.cpp:1778
std::string getAttribute(SumoXMLAttr key) const override
Definition GNELane.cpp:689
void setIndex(int index)
Definition GNELane.cpp:647
void drawArrows(const GUIVisualizationSettings &s, const RGBColor &laneColor=RGBColor(false)) const
draw lane arrows
Definition GNELane.cpp:1286
void setSpecialColor(const RGBColor *Color2, double colorValue=std::numeric_limits< double >::max())
Definition GNELane.cpp:903
void drawGL(const GUIVisualizationSettings &s) const override
Draws the object.
Definition GNELane.cpp:461
const GUIGeometry & getLaneGeometry() const
get lane geometry
Definition GNELane.cpp:228
bool checkDrawMoveContour() const override
check if draw move contour (red)
Definition GNELane.cpp:449
Position getAttributePosition(SumoXMLAttr key) const override
Definition GNELane.cpp:752
double getAttributeDouble(SumoXMLAttr key) const override
Definition GNELane.cpp:746
void setAttribute(SumoXMLAttr key, const std::string &value, GNEUndoList *undoList) override
Definition GNELane.cpp:780
void updateCenteringBoundary(const bool updateGrid)
update centering boundary (implies change in RTREE)
Definition GNELane.cpp:635
void drawLane(const GUIVisualizationSettings &s, const double layer) const
draw lane
Definition GNELane.cpp:1006
double mySpecialColorValue
optional value that corresponds to which the special color corresponds
Definition GNELane.h:381
void drawChildren(const GUIVisualizationSettings &s) const
draw children
Definition GNELane.cpp:1108
Parameterised * getParameters() override
get parameters associated with this lane
Definition GNELane.cpp:204
std::vector< Position > myLaneRestrictedTexturePositions
Position of textures of restricted lanes.
Definition GNELane.h:371
long onDefault(FXObject *, FXSelector, void *) override
multiplexes message to two targets
Definition GNELane.cpp:1936
bool checkDrawDeleteContour() const override
check if draw delete contour (pink/white)
Definition GNELane.cpp:407
double getLaneShapeLength() const
returns the length of the lane's shape
Definition GNELane.cpp:671
void updateGLObject() override
update GLObject (geometry, ID, etc.)
Definition GNELane.cpp:497
void drawStartEndGeometryPoints(const GUIVisualizationSettings &s) const
draw start and end geometry points
Definition GNELane.cpp:1856
std::vector< RGBColor > myShapeColors
The color of the shape parts (cached)
Definition GNELane.h:384
bool checkDrawDeleteContourSmall() const override
check if draw delete contour small (pink/white)
Definition GNELane.cpp:425
bool setFunctionalColor(int activeScheme, RGBColor &col) const
sets the color according to the current scheme index and some lane function
Definition GNELane.cpp:1539
bool isVisible(const GUIVisualizationSettings &s) const override
check if object is visible (Currently used only in netedit)
Definition GNELane.cpp:1924
void updateConnectionIDs()
update IDs of incoming connections of this lane
Definition GNELane.cpp:1979
void buildRechableOperations(GUISUMOAbstractView &parent, GUIGLObjectPopupMenu *ret)
build rechable operations contextual menu
Definition GNELane.cpp:2211
bool isValid(SumoXMLAttr key, const std::string &value) override
Definition GNELane.cpp:816
bool isAttributeEnabled(SumoXMLAttr key) const override
Definition GNELane.cpp:877
void drawLane2LaneConnections() const
draw lane to lane connections
Definition GNELane.cpp:1377
void buildEdgeOperations(GUISUMOAbstractView &parent, GUIGLObjectPopupMenu *ret)
build edge operations contextual menu
Definition GNELane.cpp:2005
const std::vector< double > & getShapeLengths() const
get lengths of the single shape parts
Definition GNELane.cpp:250
void drawLinkNo(const GUIVisualizationSettings &s) const
draw link Number
Definition GNELane.cpp:1212
double getSpeed() const
returns the current speed of lane
Definition GNELane.cpp:654
void drawTextures(const GUIVisualizationSettings &s) const
draw lane textures
Definition GNELane.cpp:1824
void deleteGLObject() override
delete element
Definition GNELane.cpp:488
GNEEdge * getParentEdge() const
get parent edge
Definition GNELane.cpp:216
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:664
GNEPathManager * getDataPathManager()
get data path manager
Definition GNENet.cpp:204
GNEPathManager * getDemandPathManager()
get demand path manager
Definition GNENet.cpp:198
GNENetHelper::AttributeCarriers * getAttributeCarriers() const
get all attribute carriers used in this net
Definition GNENet.cpp:174
bool isNetRecomputed() const
check if net require recomputing
Definition GNENet.cpp:1626
GNEPathManager * getNetworkPathManager()
get network path manager
Definition GNENet.cpp:192
GNEViewParent * getViewParent() const
get view parent (used for simplify code)
Definition GNENet.cpp:150
NBEdgeCont & getEdgeCont()
returns the NBEdgeCont of the underlying netbuilder
Definition GNENet.cpp:2209
GNEUndoList * getUndoList() const
get undo list(used for simplify code)
Definition GNENet.cpp:156
GNEViewNet * getViewNet() const
get view net (used for simplify code)
Definition GNENet.cpp:144
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 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
GNEAttributeCarrier * getCurrentTemplateAC() const
get current templateAC
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)
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
GNEAdditionalFrame * getAdditionalFrame() const
get frame for NETWORK_ADDITIONAL
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 drawSymbols, 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 setGLObjectParent(GUIGlObject *parent)
notify object about popup menu removal
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
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 GUIVisualizationSettings &s, 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:146
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:2236
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:4534
SVCPermissions getPermissions(int lane=-1) const
get the union of allowed classes over all lanes or for a specific lane
Definition NBEdge.cpp:4543
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:4506
void setSpeed(int lane, double speed)
set lane specific speed (negative lane implies set for all lanes)
Definition NBEdge.cpp:4458
NBNode * getToNode() const
Returns the destination node of the edge.
Definition NBEdge.h:552
Lane & getLaneStruct(int lane)
Definition NBEdge.h:1451
bool isBidiRail(bool ignoreSpread=false) const
whether this edge is part of a bidirectional railway
Definition NBEdge.cpp:772
const std::string & getID() const
Definition NBEdge.h:1551
void setLaneWidth(int lane, double width)
set lane specific width (negative lane implies set for all lanes)
Definition NBEdge.cpp:4329
void setAcceleration(int lane, bool accelRamp)
marks one lane as acceleration lane
Definition NBEdge.cpp:4490
bool isBidiEdge(bool checkPotential=false) const
whether this edge is part of a bidirectional edge pair
Definition NBEdge.cpp:784
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:4474
std::string getLaneID(int lane) const
get lane ID
Definition NBEdge.cpp:4181
void setLaneShape(int lane, const PositionVector &shape)
sets a custom lane shape
Definition NBEdge.cpp:4498
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:4412
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:2507
An upper class for objects with additional parameters.
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
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:211
unsigned char alpha() const
Returns the alpha-amount of the color.
Definition RGBColor.cpp:96
int getBrightness() const
return the perceived brightness (0-255)
Definition RGBColor.cpp:204
static RGBColor fromHSV(double h, double s, double v, bool random=false)
Converts the given hsv-triplet to rgb, inspired by http://alvyray.com/Papers/CG/hsv2rgb....
Definition RGBColor.cpp:431
static const RGBColor ORANGE
Definition RGBColor.h:210
static const RGBColor CYAN
Definition RGBColor.h:208
bool isValid() const
check if RGBColor is valid
Definition RGBColor.cpp:124
static const RGBColor GREEN
Definition RGBColor.h:205
static const RGBColor BLACK
Definition RGBColor.h:212
RGBColor changedBrightness(int change, int toChange=3) const
Returns a new color with altered brightness.
Definition RGBColor.cpp:228
RGBColor getContrastingColor() const
return a contrasting color for markings/arrows (darkened if bright, white if dark)
Definition RGBColor.cpp:210
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
unsigned node
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