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 // update centering boundary without updating grid
172}
173
174
176 GNENetworkElement(nullptr, "dummyConstructorGNELane", SUMO_TAG_LANE),
177 myMoveElementLane(new GNEMoveElementLane(this)),
178 myIndex(-1),
179 myDrawingConstants(nullptr),
180 mySpecialColor(nullptr),
181 mySpecialColorValue(-1),
182 myLane2laneConnections(this) {
183}
184#ifdef _MSC_VER
185#pragma warning(pop)
186#endif
187
189 if (myDrawingConstants) {
190 delete myDrawingConstants;
191 }
192}
193
194
199
200
203 return &(getParentEdges().front()->getNBEdge()->getLaneStruct(myIndex));
204}
205
206
207const Parameterised*
209 return &(getParentEdges().front()->getNBEdge()->getLaneStruct(myIndex));
210}
211
212
213GNEEdge*
215 return getParentEdges().front();
216}
217
218
219bool
221 return (getParentEdges().front()->getNBEdge()->getPermissions(myIndex) & SVC_PEDESTRIAN) > 0;
222}
223
224
225const GUIGeometry&
227 return myLaneGeometry;
228}
229
230
231const PositionVector&
233 if (getParentEdges().front()->getNBEdge()->getLaneStruct(myIndex).customShape.size() > 0) {
234 return getParentEdges().front()->getNBEdge()->getLaneStruct(myIndex).customShape;
235 } else {
236 return getParentEdges().front()->getNBEdge()->getLaneShape(myIndex);
237 }
238}
239
240
241const std::vector<double>&
245
246
247const std::vector<double>&
251
252
257
258
259void
261 // Clear texture containers
264 // get lane shape and extend if is too short
265 auto laneShape = getLaneShape();
266 if (laneShape.length2D() < 1) {
267 laneShape.extrapolate2D(1 - laneShape.length2D());
268 }
269 // Obtain lane shape of NBEdge
271 // update connections
273 // update additionals children associated with this lane
274 for (const auto& additional : getParentAdditionals()) {
275 additional->updateGeometry();
276 }
277 // update additionals parents associated with this lane
278 for (const auto& additional : getChildAdditionals()) {
279 additional->updateGeometry();
280 }
281 // update partial demand elements parents associated with this lane
282 for (const auto& demandElement : getParentDemandElements()) {
283 demandElement->updateGeometry();
284 }
285 // update partial demand elements children associated with this lane
286 for (const auto& demandElement : getChildDemandElements()) {
287 demandElement->updateGeometry();
288 }
289 // Update geometry of parent generic datas that have this edge as parent
290 for (const auto& additionalParent : getParentGenericDatas()) {
291 additionalParent->updateGeometry();
292 }
293 // Update geometry of additionals generic datas vinculated to this edge
294 for (const auto& childAdditionals : getChildGenericDatas()) {
295 childAdditionals->updateGeometry();
296 }
297 // compute geometry of path elements elements vinculated with this lane (depending of showDemandElements)
299 for (const auto& childAdditional : getChildAdditionals()) {
300 childAdditional->computePathElement();
301 }
302 for (const auto& childDemandElement : getChildDemandElements()) {
303 childDemandElement->computePathElement();
304 }
305 for (const auto& childGenericData : getChildGenericDatas()) {
306 childGenericData->computePathElement();
307 }
308 }
309 // in Move mode, connections aren't updated
311 // Update incoming connections of this lane
312 const auto incomingConnections = getGNEIncomingConnections();
313 for (const auto& connection : incomingConnections) {
314 connection->updateGeometry();
315 }
316 // Update outgoings connections of this lane
317 const auto outGoingConnections = getGNEOutcomingConnections();
318 for (const auto& connection : outGoingConnections) {
319 connection->markConnectionGeometryDeprecated();
320 connection->updateGeometry();
321 }
322 }
323 // if lane has enought length for show textures of restricted lanes
324 if ((getLaneShapeLength() > 4)) {
325 // if lane is restricted
327 // get values for position and rotation of icons
328 for (int i = 2; i < getLaneShapeLength() - 1; i += 15) {
331 }
332 }
333 }
334}
335
336
339 return getLaneShape().positionAtOffset2D(getLaneShape().length2D() * 0.5);
340}
341
342
343bool
345 const auto& inspectedElements = myNet->getViewNet()->getInspectedElements();
346 // check if we're inspecting a connection
347 if (inspectedElements.isInspectingSingleElement() && (inspectedElements.getFirstAC()->getTagProperty()->getTag() == SUMO_TAG_CONNECTION) &&
348 inspectedElements.getFirstAC()->getAttribute(GNE_ATTR_FROM_LANEID) == getID()) {
349 return true;
350 } else {
351 return false;
352 }
353}
354
355
356bool
358 const auto& inspectedElements = myNet->getViewNet()->getInspectedElements();
359 // check if we're inspecting a connection
360 if (inspectedElements.isInspectingSingleElement() && (inspectedElements.getFirstAC()->getTagProperty()->getTag() == SUMO_TAG_CONNECTION) &&
361 inspectedElements.getFirstAC()->getAttribute(GNE_ATTR_TO_LANEID) == getID()) {
362 return true;
363 } else {
364 return false;
365 }
366}
367
368
369bool
371 // check opened popup
372 if (myNet->getViewNet()->getPopup()) {
373 return myNet->getViewNet()->getPopup()->getGLObject() == this;
374 }
375 return false;
376}
377
378
379bool
381 // get modes and viewParent (for code legibility)
382 const auto& modes = myNet->getViewNet()->getEditModes();
383 const auto& viewParent = myNet->getViewParent();
384 // check if we're selecting edges in additional mode
385 if (modes.isCurrentSupermodeNetwork() && (modes.networkEditMode == NetworkEditMode::NETWORK_ADDITIONAL)) {
386 if (viewParent->getAdditionalFrame()->getViewObjetsSelector()->isNetworkElementSelected(this)) {
387 return true;
388 } else if (viewParent->getAdditionalFrame()->getViewObjetsSelector()->getTag() == myTagProperty->getTag()) {
390 } else {
391 return false;
392 }
393 } else {
394 return false;
395 }
396}
397
398
399bool
401 // first check if we're selecting edges or lanes
403 return false;
404 } else {
405 // get edit modes
406 const auto& editModes = myNet->getViewNet()->getEditModes();
407 // check if we're in delete mode
408 if (editModes.isCurrentSupermodeNetwork() && (editModes.networkEditMode == NetworkEditMode::NETWORK_DELETE)) {
410 } else {
411 return false;
412 }
413 }
414}
415
416
417bool
419 return false;
420}
421
422
423bool
425 // first check if we're selecting edges or lanes
427 return false;
428 } else {
429 // get edit modes
430 const auto& editModes = myNet->getViewNet()->getEditModes();
431 // check if we're in select mode
432 if (editModes.isCurrentSupermodeNetwork() && (editModes.networkEditMode == NetworkEditMode::NETWORK_SELECT)) {
434 } else {
435 return false;
436 }
437 }
438}
439
440
441bool
443 // check if we're editing this network element
445 if (editedNetworkElement) {
446 return editedNetworkElement == this;
447 } else {
448 return false;
449 }
450}
451
452
453void
455 // update lane drawing constan
457 // calculate layer
458 double layer = GLO_LANE;
459 if (getParentEdges().front()->isMarkedForDrawingFront()) {
460 layer = GLO_FRONTELEMENT;
462 layer = GLO_JUNCTION + 2;
463 }
464 // check drawing conditions
466 // draw lane
467 drawLane(s, layer);
468 // draw lock icon
470 // draw dotted contour
472 }
473 // calculate contour (always before children)
474 calculateLaneContour(s, layer);
475 // draw children
476 drawChildren(s);
477}
478
479
480void
482 // Check if edge can be deleted
484 myNet->deleteLane(this, myNet->getUndoList(), false);
485 }
486}
487
488
489void
493
494
495
498 // first obtain edit mode (needed because certain Commands depend of current edit mode)
500 // get mouse position
501 const auto mousePosition = myNet->getViewNet()->getPositionInformation();
502 GUIGLObjectPopupMenu* ret = new GUIGLObjectPopupMenu(app, parent, this);
503 buildPopupHeader(ret, app);
505 // build copy names entry
506 if (editMode != NetworkEditMode::NETWORK_TLS) {
507 GUIDesigns::buildFXMenuCommand(ret, TL("Copy parent edge name to clipboard"), nullptr, ret, MID_COPY_EDGE_NAME);
509 }
510 // stop if we're in data mode
512 return ret;
513 }
514 // build lane selection
517 } else {
519 }
520 // build edge selection
523 } else {
525 }
526 // stop if we're in data mode
528 return ret;
529 }
530 // add separator
531 new FXMenuSeparator(ret);
532 if (editMode != NetworkEditMode::NETWORK_TLS) {
533 // build show parameters menu
535 // build position copy entry
536 buildPositionCopyEntry(ret, app);
537 }
538 // check if we're in supermode network
540 // create end point
541 FXMenuCommand* resetEndPoints = GUIDesigns::buildFXMenuCommand(ret, TL("Reset edge end points"), nullptr, &parent, MID_GNE_RESET_GEOMETRYPOINT);
542 // enable or disable reset end points
543 if (getParentEdges().front()->hasCustomEndPoints()) {
544 resetEndPoints->enable();
545 } else {
546 resetEndPoints->disable();
547 }
548 // check if we clicked over a geometry point
549 if ((editMode == NetworkEditMode::NETWORK_MOVE) && getParentEdges().front()->clickedOverGeometryPoint(mousePosition)) {
550 GUIDesigns::buildFXMenuCommand(ret, TL("Set custom Geometry Point"), nullptr, &parent, MID_GNE_CUSTOM_GEOMETRYPOINT);
551 }
552 // add separator
553 new FXMenuSeparator(ret);
554 //build operations
555 if ((editMode != NetworkEditMode::NETWORK_CONNECT) && (editMode != NetworkEditMode::NETWORK_TLS)) {
556 // build edge operations
557 buildEdgeOperations(parent, ret);
558 // build lane operations
559 buildLaneOperations(parent, ret);
560 // build template operations
561 buildTemplateOperations(parent, ret);
562 // add separator
563 new FXMenuSeparator(ret);
564 // build rechable operations
565 buildRechableOperations(parent, ret);
566 } else if (editMode == NetworkEditMode::NETWORK_TLS) {
568 GUIDesigns::buildFXMenuCommand(ret, TL("Select state for all links from this edge:"), nullptr, nullptr, 0);
569 const std::vector<std::string> names = GNEInternalLane::LinkStateNames.getStrings();
570 for (auto it : names) {
571 FXuint state = GNEInternalLane::LinkStateNames.get(it);
572 FXMenuRadio* mc = new FXMenuRadio(ret, it.c_str(), this, FXDataTarget::ID_OPTION + state);
575 }
576 }
577 } else {
578 FXMenuCommand* mc = GUIDesigns::buildFXMenuCommand(ret, TL("Additional options available in 'Inspect Mode'"), nullptr, nullptr, 0);
579 mc->handle(&parent, FXSEL(SEL_COMMAND, FXWindow::ID_DISABLE), nullptr);
580 }
581 // build shape positions menu
582 if (editMode != NetworkEditMode::NETWORK_TLS) {
583 new FXMenuSeparator(ret);
584 // get lane shape
585 const auto& laneShape = myLaneGeometry.getShape();
586 // get variables
587 const double pos = laneShape.nearest_offset_to_point2D(mousePosition);
588 const Position firstAnglePos = laneShape.positionAtOffset2D(pos - 0.001);
589 const Position secondAnglePos = laneShape.positionAtOffset2D(pos);
590 const double angle = firstAnglePos.angleTo2D(secondAnglePos);
591
592 // build menu commands
593 GUIDesigns::buildFXMenuCommand(ret, TL("Shape pos: ") + toString(pos), nullptr, nullptr, 0);
594 GUIDesigns::buildFXMenuCommand(ret, TL("Length pos: ") + toString(pos * getLaneParametricLength() / getLaneShapeLength()), nullptr, nullptr, 0);
595 if (getParentEdges().front()->getNBEdge()->getDistance() != 0) {
596 GUIDesigns::buildFXMenuCommand(ret, TL("Distance: ") + toString(getParentEdges().front()->getNBEdge()->getDistancAt(pos)), nullptr, nullptr, 0);
597 }
598 GUIDesigns::buildFXMenuCommand(ret, TL("Height: ") + toString(firstAnglePos.z()), nullptr, nullptr, 0);
599 GUIDesigns::buildFXMenuCommand(ret, TL("Angle: ") + toString((GeomHelper::naviDegree(angle))), nullptr, nullptr, 0);
600 }
601 }
602 return ret;
603}
604
605
606double
608 return s.addSize.getExaggeration(s, this);
609}
610
611
616
617
618void
619GNELane::updateCenteringBoundary(const bool /*updateGrid*/) {
620 // nothing to update
621}
622
623
624int
626 return myIndex;
627}
628
629
630void
632 myIndex = index;
633 setNetworkElementID(getParentEdges().front()->getNBEdge()->getLaneID(index));
634}
635
636
637double
639 return getParentEdges().front()->getNBEdge()->getLaneSpeed(myIndex);
640}
641
642
643double
645 double laneParametricLength = getParentEdges().front()->getNBEdge()->getLoadedLength();
646 if (laneParametricLength > 0) {
647 return laneParametricLength;
648 } else {
649 throw ProcessError(TL("Lane Parametric Length cannot be never 0"));
650 }
651}
652
653
654double
658
659
660bool
662 return getParentEdges().front()->getNBEdge()->getPermissions(myIndex) == vclass;
663}
664
665
670
671
672std::string
674 const NBEdge* edge = getParentEdges().front()->getNBEdge();
675 switch (key) {
676 case SUMO_ATTR_ID:
677 return getMicrosimID();
679 return getParentEdges().front()->getFromJunction()->getID();
681 return getParentEdges().front()->getToJunction()->getID();
682 case SUMO_ATTR_SPEED:
683 return toString(edge->getLaneSpeed(myIndex));
684 case SUMO_ATTR_ALLOW:
692 case SUMO_ATTR_WIDTH:
694 return "default";
695 } else {
696 return toString(edge->getLaneStruct(myIndex).width);
697 }
699 return toString(edge->getLaneStruct(myIndex).friction);
704 case SUMO_ATTR_SHAPE:
709 case SUMO_ATTR_TYPE:
710 return edge->getLaneStruct(myIndex).type;
711 case SUMO_ATTR_INDEX:
712 return toString(myIndex);
718 } else {
719 return "";
720 }
721 case GNE_ATTR_PARENT:
722 return getParentEdges().front()->getID();
723 default:
724 return getCommonAttribute(key);
725 }
726}
727
728
729double
733
734
739
740
743 switch (key) {
744 case SUMO_ATTR_SHAPE:
746 return getParentEdges().front()->getNBEdge()->getLaneStruct(myIndex).customShape;
747 default:
749 }
750}
751
752
753std::string
755 std::string result = getAttribute(key);
756 if ((key == SUMO_ATTR_ALLOW || key == SUMO_ATTR_DISALLOW) && result.find("all") != std::string::npos) {
757 result += " " + getVehicleClassNames(SVCAll, true);
758 }
759 return result;
760}
761
762
763void
764GNELane::setAttribute(SumoXMLAttr key, const std::string& value, GNEUndoList* undoList) {
765 switch (key) {
766 case SUMO_ATTR_ID:
767 throw InvalidArgument("Modifying attribute '" + toString(key) + "' of " + getTagStr() + " isn't allowed");
768 case SUMO_ATTR_SPEED:
769 case SUMO_ATTR_ALLOW:
773 case SUMO_ATTR_WIDTH:
777 case SUMO_ATTR_SHAPE:
780 case SUMO_ATTR_TYPE:
781 case SUMO_ATTR_INDEX:
783 // special case for stop offset, because affects to stopOffsetExceptions (#15297)
784 if (canParse<double>(value) && (parse<double>(value) == 0)) {
786 }
787 GNEChange_Attribute::changeAttribute(this, key, value, undoList);
788 break;
790 GNEChange_Attribute::changeAttribute(this, key, value, undoList);
791 break;
792 default:
793 setCommonAttribute(key, value, undoList);
794 break;
795 }
796}
797
798
799bool
800GNELane::isValid(SumoXMLAttr key, const std::string& value) {
801 switch (key) {
802 case SUMO_ATTR_ID:
803 case SUMO_ATTR_INDEX:
804 return false;
805 case SUMO_ATTR_SPEED:
806 return canParse<double>(value);
807 case SUMO_ATTR_ALLOW:
811 return canParseVehicleClasses(value);
812 case SUMO_ATTR_WIDTH:
813 if (value.empty() || (value == "default")) {
814 return true;
815 } else {
816 return canParse<double>(value) && ((parse<double>(value) > 0) || (parse<double>(value) == NBEdge::UNSPECIFIED_WIDTH));
817 }
820 return canParse<double>(value) && (parse<double>(value) >= 0);
822 return canParse<bool>(value);
823 case SUMO_ATTR_SHAPE:
825 // A lane shape can either be empty or have more than 1 element
826 if (value.empty()) {
827 return true;
828 } else if (canParse<PositionVector>(value)) {
829 return parse<PositionVector>(value).size() > 1;
830 }
831 return false;
832 case GNE_ATTR_OPPOSITE: {
833 if (value.empty()) {
834 return true;
835 } else {
836 NBEdge* oppEdge = myNet->getEdgeCont().retrieve(value.substr(0, value.rfind("_")));
837 if (oppEdge == nullptr || oppEdge->getLaneID(oppEdge->getNumLanes() - 1) != value) {
838 return false;
839 }
840 NBEdge* edge = getParentEdges().front()->getNBEdge();
841 if (oppEdge->getFromNode() != edge->getToNode() || oppEdge->getToNode() != edge->getFromNode()) {
842 WRITE_WARNINGF(TL("Opposite lane '%' does not connect the same nodes as edge '%'!"), value, edge->getID());
843 return false;
844 }
845 return true;
846 }
847 }
848 case SUMO_ATTR_TYPE:
849 return true;
851 return canParse<double>(value) && (parse<double>(value) >= 0);
853 return canParseVehicleClasses(value);
854 default:
855 return isCommonAttributeValid(key, value);
856 }
857}
858
859
860bool
862 switch (key) {
863 case SUMO_ATTR_ID:
864 case SUMO_ATTR_INDEX:
865 return false;
867 return getParentEdges().front()->getNBEdge()->getLaneStruct(myIndex).laneStopOffset.getOffset() > 0;
868 default:
869 return true;
870 }
871}
872
873
874bool
876 const NBEdge* edge = getParentEdges().front()->getNBEdge();
877 switch (key) {
878 case SUMO_ATTR_WIDTH:
880 default:
881 return false;
882 }
883}
884
885
886void
887GNELane::setSpecialColor(const RGBColor* color, double colorValue) {
888 mySpecialColor = color;
889 mySpecialColorValue = colorValue;
890}
891
892// ===========================================================================
893// private
894// ===========================================================================
895
896void
897GNELane::setAttribute(SumoXMLAttr key, const std::string& value) {
898 // get parent edge
899 NBEdge* edge = getParentEdges().front()->getNBEdge();
900 // get template editor
902 // check if we have to update template
903 const bool updateTemplate = templateEditor->getEdgeTemplate() ? (templateEditor->getEdgeTemplate()->getID() == getParentEdges().front()->getID()) : false;
904 switch (key) {
905 case SUMO_ATTR_ID:
906 case SUMO_ATTR_INDEX:
907 throw InvalidArgument("Modifying attribute '" + toString(key) + "' of " + getTagStr() + " isn't allowed");
908 case SUMO_ATTR_SPEED:
909 edge->setSpeed(myIndex, parse<double>(value));
910 break;
911 case SUMO_ATTR_ALLOW:
913 break;
916 break;
919 break;
922 break;
923 case SUMO_ATTR_WIDTH:
924 if (value.empty() || (value == "default")) {
926 } else {
927 edge->setLaneWidth(myIndex, parse<double>(value));
928 }
929 // update edge parent boundary
930 getParentEdges().front()->updateCenteringBoundary(true);
931 break;
933 edge->setFriction(myIndex, parse<double>(value));
934 break;
936 edge->setEndOffset(myIndex, parse<double>(value));
937 break;
939 edge->setAcceleration(myIndex, parse<bool>(value));
940 break;
941 case SUMO_ATTR_SHAPE:
943 // set new shape
944 edge->setLaneShape(myIndex, parse<PositionVector>(value));
945 // update edge parent boundary
946 getParentEdges().front()->updateCenteringBoundary(true);
947 break;
948 case GNE_ATTR_OPPOSITE: {
949 if (value != "") {
950 NBEdge* oppEdge = myNet->getEdgeCont().retrieve(value.substr(0, value.rfind("_")));
951 oppEdge->getLaneStruct(oppEdge->getNumLanes() - 1).oppositeID = getID();
952 } else {
953 // reset prior oppEdge if existing
954 const std::string oldValue = getParentEdges().front()->getNBEdge()->getLaneStruct(myIndex).oppositeID;
955 NBEdge* oppEdge = myNet->getEdgeCont().retrieve(oldValue.substr(0, oldValue.rfind("_")));
956 if (oppEdge != nullptr) {
957 oppEdge->getLaneStruct(oppEdge->getNumLanes() - 1).oppositeID = "";
958 }
959 }
960 getParentEdges().front()->getNBEdge()->getLaneStruct(myIndex).oppositeID = value;
961 break;
962 }
963 case SUMO_ATTR_TYPE:
964 edge->getLaneStruct(myIndex).type = value;
965 break;
967 if (value.empty()) {
969 } else {
970 edge->getLaneStruct(myIndex).laneStopOffset.setOffset(parse<double>(value));
971 }
972 break;
975 break;
976 default:
977 setCommonAttribute(key, value);
978 break;
979 }
980 // update template
981 if (updateTemplate) {
982 templateEditor->setEdgeTemplate(getParentEdges().front());
983 }
984 // invalidate demand path calculator
986}
987
988
989void
990GNELane::drawLane(const GUIVisualizationSettings& s, const double layer) const {
991 // Push layer matrix
993 // translate to layer
994 drawInLayer(layer);
995 // set lane colors
996 RGBColor laneColor = setLaneColor(s);
997 // never draw when at full transparency
998 if (laneColor.alpha() != 0) {
999 // Check if lane has to be draw as railway and if isn't being drawn for selecting
1001 // draw as railway
1003 } else if (myShapeColors.size() > 0) {
1004 // draw geometry with own colors
1007 } else {
1008 // draw geometry with current color
1010 double drawingWidth = myDrawingConstants->getDrawingWidth();
1012 drawingWidth = myNet->getViewNet()->m2p(drawingWidth);
1013 }
1016 }
1017 // if lane is selected, draw a second lane over it
1019 // draw start end shape points
1021 // check if draw details
1023 // draw markings
1025 // Draw direction indicators
1027 // draw lane textures
1028 drawTextures(s);
1029 // draw lane arrows
1030 drawArrows(s);
1031 // draw link numbers
1032 drawLinkNo(s);
1033 // draw TLS link numbers
1034 drawTLSLinkNo(s);
1035 // draw stopOffsets
1037 }
1038 // draw shape edited
1039 drawShapeEdited(s);
1040 }
1041 // Pop layer matrix
1043}
1044
1045
1046void
1048 // only draw if lane is selected
1049 if (drawUsingSelectColor()) {
1050 // Push matrix
1052 // move back
1053 glTranslated(0, 0, 0.1);
1054 // set selected edge color
1056 // draw geometry with current color
1059 // Pop matrix
1061 }
1062}
1063
1064
1065void
1067 // if shape is being edited, draw point and green line
1068 if (myShapeEdited) {
1069 // push shape edited matrix
1071 // translate
1073 // set selected edge color
1075 // draw shape around
1078 // move front
1079 glTranslated(0, 0, 1);
1080 // draw geometry points
1085 // Pop shape edited matrix
1087 }
1088}
1089
1090
1091void
1093 // draw additional children
1094 for (const auto& additional : getChildAdditionals()) {
1095 if (!additional->getTagProperty()->isListedElement()) {
1096 additional->drawGL(s);
1097 }
1098 }
1099 // draw demand element children
1100 for (const auto& demandElement : getChildDemandElements()) {
1101 if (!demandElement->getTagProperty()->isPlacedInRTree()) {
1102 demandElement->drawGL(s);
1103 }
1104 }
1105 // draw path additional elements
1109}
1110
1111
1112void
1114 // check conditions
1116 // check if this is the last lane (note: First lane is the lane more far of the edge's center)
1117 const bool firstlane = (myIndex == 0);
1118 const bool lastLane = (myIndex == (getParentEdges().front()->getNBEdge()->getNumLanes() - 1));
1119 // declare separator width
1120 const auto separatorWidth = SUMO_const_laneMarkWidth * 0.5;
1121 // get passengers change left and right for previous, current and next lane
1122 const bool changeRightTop = lastLane ? true : getParentEdges().front()->getNBEdge()->allowsChangingRight(myIndex + 1, SVC_PASSENGER);
1123 const bool changeLeftCurrent = lastLane ? true : getParentEdges().front()->getNBEdge()->allowsChangingLeft(myIndex, SVC_PASSENGER);
1124 const bool changeRightCurrent = firstlane ? true : getParentEdges().front()->getNBEdge()->allowsChangingRight(myIndex, SVC_PASSENGER);
1125 const bool changeLeftBot = firstlane ? true : getParentEdges().front()->getNBEdge()->allowsChangingLeft(myIndex - 1, SVC_PASSENGER);
1126 // save current color
1127 const auto currentColor = GLHelper::getColor();
1128 // separator offsets
1129 const double topSeparatorOffset = myDrawingConstants->getOffset() + (myDrawingConstants->getDrawingWidth() * -1) + separatorWidth;
1130 const double botSeparatorOffset = myDrawingConstants->getOffset() + myDrawingConstants->getDrawingWidth() - separatorWidth;
1131 // push matrix
1133 // translate
1134 glTranslated(0, 0, 0.1);
1135 // continue depending of lanes
1136 if (myDrawingConstants->drawSuperposed() || (firstlane && lastLane)) {
1137 // draw top and bot separator only
1139 GUIGeometry::drawGeometry(myDrawingConstants->getDetail(), myLaneGeometry, separatorWidth, topSeparatorOffset);
1140 GUIGeometry::drawGeometry(myDrawingConstants->getDetail(), myLaneGeometry, separatorWidth, botSeparatorOffset);
1141 } else if (firstlane) {
1142 // draw top separator
1143 GLHelper::setColor((changeLeftCurrent && changeRightTop) ? RGBColor::WHITE : RGBColor::ORANGE);
1144 GUIGeometry::drawGeometry(myDrawingConstants->getDetail(), myLaneGeometry, separatorWidth, topSeparatorOffset);
1145 // check if draw inverse marking
1146 if (changeLeftCurrent) {
1147 GLHelper::setColor(currentColor);
1149 3, 6, topSeparatorOffset, true, true, s.lefthand, 1);
1150 }
1151 // draw bot separator
1153 GUIGeometry::drawGeometry(myDrawingConstants->getDetail(), myLaneGeometry, separatorWidth, botSeparatorOffset);
1154 } else if (lastLane) {
1155 // draw top separator
1157 GUIGeometry::drawGeometry(myDrawingConstants->getDetail(), myLaneGeometry, separatorWidth, topSeparatorOffset);
1158 // draw bot separator
1159 GLHelper::setColor((changeRightCurrent && changeLeftBot) ? RGBColor::WHITE : RGBColor::ORANGE);
1160 GUIGeometry::drawGeometry(myDrawingConstants->getDetail(), myLaneGeometry, separatorWidth, botSeparatorOffset);
1161 // check if draw inverse marking
1162 if (changeRightCurrent) {
1163 GLHelper::setColor(currentColor);
1165 3, 6, botSeparatorOffset, true, true, s.lefthand, 1);
1166 }
1167 } else {
1168 // draw top separator
1169 GLHelper::setColor((changeLeftCurrent && changeRightTop) ? RGBColor::WHITE : RGBColor::ORANGE);
1170 GUIGeometry::drawGeometry(myDrawingConstants->getDetail(), myLaneGeometry, separatorWidth, topSeparatorOffset);
1171 // check if draw inverse marking
1172 if (changeLeftCurrent) {
1173 GLHelper::setColor(currentColor);
1175 3, 6, topSeparatorOffset, true, true, s.lefthand, 1);
1176 }
1177 // draw bot separator
1178 GLHelper::setColor((changeRightCurrent && changeLeftBot) ? RGBColor::WHITE : RGBColor::ORANGE);
1179 GUIGeometry::drawGeometry(myDrawingConstants->getDetail(), myLaneGeometry, separatorWidth, botSeparatorOffset);
1180 // check if draw inverse marking
1181 if (changeRightCurrent) {
1182 GLHelper::setColor(currentColor);
1184 3, 6, botSeparatorOffset, true, true, s.lefthand, 1);
1185 }
1186 }
1187 // pop matrix
1189 }
1190}
1191
1192
1193void
1195 // check draw conditions
1196 if (s.drawLinkJunctionIndex.show(getParentEdges().front()->getToJunction())) {
1197 // get connections
1198 const auto& connections = getParentEdges().front()->getNBEdge()->getConnectionsFromLane(myIndex);
1199 // get number of links
1200 const int noLinks = (int)connections.size();
1201 // only continue if there is links
1202 if (noLinks > 0) {
1203 // push link matrix
1205 // move front
1206 glTranslated(0, 0, GLO_TEXTNAME);
1207 // calculate width
1208 const double width = getParentEdges().front()->getNBEdge()->getLaneWidth(myIndex) / (double) noLinks;
1209 // get X1
1210 double x1 = getParentEdges().front()->getNBEdge()->getLaneWidth(myIndex) / 2;
1211 // iterate over links
1212 for (int i = noLinks - 1; i >= 0; i--) {
1213 // calculate x2
1214 const double x2 = x1 - (double)(width / 2.);
1215 // get link index
1216 const int linkIndex = getParentEdges().front()->getNBEdge()->getToNode()->getConnectionIndex(getParentEdges().front()->getNBEdge(),
1217 connections[s.lefthand ? noLinks - 1 - i : i]);
1218 // draw link index
1220 // update x1
1221 x1 -= width;
1222 }
1223 // pop link matrix
1225 }
1226 }
1227}
1228
1229
1230void
1232 // check conditions
1234 (getParentEdges().front()->getToJunction()->getNBNode()->getControllingTLS().size() > 0)) {
1235 // get connections
1236 const auto& connections = getParentEdges().front()->getNBEdge()->getConnectionsFromLane(myIndex);
1237 // get numer of links
1238 const int noLinks = (int)connections.size();
1239 // only continue if there are links
1240 if (noLinks > 0) {
1241 // push link matrix
1243 // move t front
1244 glTranslated(0, 0, GLO_TEXTNAME);
1245 // calculate width
1246 const double w = getParentEdges().front()->getNBEdge()->getLaneWidth(myIndex) / (double) noLinks;
1247 // calculate x1
1248 double x1 = getParentEdges().front()->getNBEdge()->getLaneWidth(myIndex) / 2;
1249 // iterate over links
1250 for (int i = noLinks - 1; i >= 0; --i) {
1251 // calculate x2
1252 const double x2 = x1 - (double)(w / 2.);
1253 // get link number
1254 const int linkNo = connections[s.lefthand ? noLinks - 1 - i : i].tlLinkIndex;
1255 // draw link number
1257 // update x1
1258 x1 -= w;
1259 }
1260 // pop link matrix
1262 }
1263 }
1264}
1265
1266
1267void
1269 if (s.showLinkDecals && getParentEdges().front()->getToJunction()->isLogicValid()) {
1270 // calculate begin, end and rotation
1271 const Position& begin = myLaneGeometry.getShape()[-2];
1272 const Position& end = myLaneGeometry.getShape().back();
1273 const double rot = GUIGeometry::calculateRotation(begin, end);
1274 // push arrow matrix
1276 // move front (note: must draw on top of junction shape?
1277 glTranslated(0, 0, 3);
1278 // change color depending of spreadSuperposed
1281 } else {
1283 }
1284 // move to end
1285 glTranslated(end.x(), end.y(), 0);
1286 // rotate
1287 glRotated(rot, 0, 0, 1);
1288 const double width = getParentEdges().front()->getNBEdge()->getLaneWidth(myIndex);
1289 if (width < SUMO_const_laneWidth) {
1291 }
1292 // apply offset
1293 glTranslated(myDrawingConstants->getOffset() * -1, 0, 0);
1294 // get destination node
1295 const NBNode* dest = getParentEdges().front()->getNBEdge()->myTo;
1296 // draw all links iterating over connections
1297 for (const auto& connection : getParentEdges().front()->getNBEdge()->myConnections) {
1298 if (connection.fromLane == myIndex) {
1299 // get link direction
1300 LinkDirection dir = dest->getDirection(getParentEdges().front()->getNBEdge(), connection.toEdge, s.lefthand);
1301 // draw depending of link direction
1302 switch (dir) {
1304 GLHelper::drawBoxLine(Position(0, 4), 0, 2, .05);
1305 GLHelper::drawTriangleAtEnd(Position(0, 4), Position(0, 1), (double) 1, (double) .25);
1306 break;
1308 GLHelper::drawBoxLine(Position(0, 4), 0, 1.5, .05);
1309 GLHelper::drawBoxLine(Position(0, 2.5), 90, 1, .05);
1310 GLHelper::drawTriangleAtEnd(Position(0, 2.5), Position(1.5, 2.5), (double) 1, (double) .25);
1311 break;
1313 GLHelper::drawBoxLine(Position(0, 4), 0, 1.5, .05);
1314 GLHelper::drawBoxLine(Position(0, 2.5), -90, 1, .05);
1315 GLHelper::drawTriangleAtEnd(Position(0, 2.5), Position(-1.5, 2.5), (double) 1, (double) .25);
1316 break;
1318 GLHelper::drawBoxLine(Position(0, 4), 0, 1.5, .05);
1319 GLHelper::drawBoxLine(Position(0, 2.5), 90, .5, .05);
1320 GLHelper::drawBoxLine(Position(0.5, 2.5), 180, 1, .05);
1321 GLHelper::drawTriangleAtEnd(Position(0.5, 2.5), Position(0.5, 4), (double) 1, (double) .25);
1322 break;
1324 GLHelper::drawBoxLine(Position(0, 4), 0, 1.5, .05);
1325 GLHelper::drawBoxLine(Position(0, 2.5), -90, 1, .05);
1326 GLHelper::drawBoxLine(Position(-0.5, 2.5), -180, 1, .05);
1327 GLHelper::drawTriangleAtEnd(Position(-0.5, 2.5), Position(-0.5, 4), (double) 1, (double) .25);
1328 break;
1330 GLHelper::drawBoxLine(Position(0, 4), 0, 1.5, .05);
1331 GLHelper::drawBoxLine(Position(0, 2.5), 45, .7, .05);
1332 GLHelper::drawTriangleAtEnd(Position(0, 2.5), Position(1.2, 1.3), (double) 1, (double) .25);
1333 break;
1335 GLHelper::drawBoxLine(Position(0, 4), 0, 1.5, .05);
1336 GLHelper::drawBoxLine(Position(0, 2.5), -45, .7, .05);
1337 GLHelper::drawTriangleAtEnd(Position(0, 2.5), Position(-1.2, 1.3), (double) 1, (double) .25);
1338 break;
1340 GLHelper::drawBoxLine(Position(1, 5.8), 245, 2, .05);
1341 GLHelper::drawBoxLine(Position(-1, 5.8), 115, 2, .05);
1342 glTranslated(0, 5, 0);
1343 GLHelper::drawOutlineCircle(0.9, 0.8, 32);
1344 glTranslated(0, -5, 0);
1345 break;
1346 default:
1347 break;
1348 }
1349 }
1350 }
1351 // pop arrow matrix
1353 }
1354}
1355
1356
1357void
1360 glTranslated(0, 0, 0.1); // must draw on top of junction shape
1361 std::vector<NBEdge::Connection> connections = getParentEdges().front()->getNBEdge()->getConnectionsFromLane(myIndex);
1362 NBNode* node = getParentEdges().front()->getNBEdge()->getToNode();
1363 const Position& startPos = myLaneGeometry.getShape()[-1];
1364 for (auto it : connections) {
1365 const LinkState state = node->getLinkState(getParentEdges().front()->getNBEdge(), it.toEdge, it.fromLane, it.toLane, it.mayDefinitelyPass, it.tlID);
1366 switch (state) {
1368 glColor3d(1, 1, 0);
1369 break;
1371 glColor3d(0, 1, 1);
1372 break;
1373 case LINKSTATE_MAJOR:
1374 glColor3d(1, 1, 1);
1375 break;
1376 case LINKSTATE_MINOR:
1377 glColor3d(.4, .4, .4);
1378 break;
1379 case LINKSTATE_STOP:
1380 glColor3d(.7, .4, .4);
1381 break;
1382 case LINKSTATE_EQUAL:
1383 glColor3d(.7, .7, .7);
1384 break;
1386 glColor3d(.7, .7, 1);
1387 break;
1388 case LINKSTATE_ZIPPER:
1389 glColor3d(.75, .5, 0.25);
1390 break;
1391 default:
1392 throw ProcessError(TLF("Unexpected LinkState '%'", toString(state)));
1393 }
1394 const Position& endPos = it.toEdge->getLaneShape(it.toLane)[0];
1395 glBegin(GL_LINES);
1396 glVertex2d(startPos.x(), startPos.y());
1397 glVertex2d(endPos.x(), endPos.y());
1398 glEnd();
1399 GLHelper::drawTriangleAtEnd(startPos, endPos, (double) 1.5, (double) .2);
1400 }
1402}
1403
1404
1405void
1406GNELane::calculateLaneContour(const GUIVisualizationSettings& s, const double layer) const {
1407 // first check if edge parent was inserted with full boundary
1408 if (!gViewObjectsHandler.checkBoundaryParentObject(s, this, layer, getParentEdges().front())) {
1409 // calculate contour
1412 true, true, myDrawingConstants->getOffset(), nullptr, getParentEdges().front());
1413 // calculate geometry points contour if we're editing shape
1414 if (myShapeEdited) {
1418 }
1419 }
1420}
1421
1422
1425 const auto& inspectedElements = myNet->getViewNet()->getInspectedElements();
1426 // declare a RGBColor variable
1427 RGBColor color;
1428 // 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.
1429 if (inspectedElements.getFirstAC() &&
1430 !inspectedElements.getFirstAC()->isAttributeCarrierSelected() &&
1431 inspectedElements.getFirstAC()->getTagProperty()->vehicleEdges()) {
1432 // obtain attribute "via"
1433 std::vector<std::string> viaEdges = parse<std::vector<std::string> >(inspectedElements.getFirstAC()->getAttribute(SUMO_ATTR_VIA));
1434 // iterate over viaEdges
1435 for (const auto& edge : viaEdges) {
1436 // check if parent edge is in the via edges
1437 if (getParentEdges().front()->getID() == edge) {
1438 // set green color in GLHelper and return it
1439 color = RGBColor::GREEN;
1440 }
1441 }
1442 }
1443 if (mySpecialColor != nullptr) {
1444 // If special color is enabled, set it
1445 color = *mySpecialColor;
1446 } else if (getParentEdges().front()->drawUsingSelectColor() && s.laneColorer.getActive() != 1) {
1447 // override with special colors (unless the color scheme is based on selection)
1449 } else {
1450 // Get normal lane color
1451 const GUIColorer& c = s.laneColorer;
1452 if (!setFunctionalColor(c.getActive(), color) && !setMultiColor(s, c, color)) {
1453 color = c.getScheme().getColor(getColorValue(s, c.getActive()));
1454 }
1455 }
1456 // special color for conflicted candidate edges
1457 if (getParentEdges().front()->isConflictedCandidate()) {
1458 // extra check for route frame
1461 }
1462 }
1463 // special color for special candidate edges
1464 if (getParentEdges().front()->isSpecialCandidate()) {
1465 // extra check for route frame
1468 }
1469 }
1470 // special color for candidate edges
1471 if (getParentEdges().front()->isPossibleCandidate()) {
1472 // extra check for route frame
1475 }
1476 }
1477 // special color for source candidate edges
1478 if (getParentEdges().front()->isSourceCandidate()) {
1480 }
1481 // special color for target candidate edges
1482 if (getParentEdges().front()->isTargetCandidate()) {
1484 }
1485 // special color for invalid candidate edges
1486 if (getParentEdges().front()->isInvalidCandidate()) {
1488 }
1489 // special color for source candidate lanes
1490 if (mySourceCandidate) {
1492 }
1493 // special color for target candidate lanes
1494 if (myTargetCandidate) {
1496 }
1497 // special color for special candidate lanes
1498 if (mySpecialCandidate) {
1500 }
1501 // special color for possible candidate lanes
1502 if (myPossibleCandidate) {
1504 }
1505 // special color for conflicted candidate lanes
1508 }
1509 // special color for invalid candidate lanes
1510 if (myInvalidCandidate) {
1512 }
1513 // set color in GLHelper
1514 GLHelper::setColor(color);
1515 return color;
1516}
1517
1518
1519bool
1520GNELane::setFunctionalColor(int activeScheme, RGBColor& col) const {
1521 switch (activeScheme) {
1522 case 6: {
1523 double hue = GeomHelper::naviDegree(myLaneGeometry.getShape().beginEndAngle()); // [0-360]
1524 col = RGBColor::fromHSV(hue, 1., 1.);
1525 return true;
1526 }
1527 default:
1528 return false;
1529 }
1530}
1531
1532
1533bool
1535 const int activeScheme = c.getActive();
1536 myShapeColors.clear();
1537 switch (activeScheme) {
1538 case 9: // color by height at segment start
1539 for (PositionVector::const_iterator ii = myLaneGeometry.getShape().begin(); ii != myLaneGeometry.getShape().end() - 1; ++ii) {
1540 myShapeColors.push_back(c.getScheme().getColor(ii->z()));
1541 }
1542 col = c.getScheme().getColor(getColorValue(s, 8));
1543 return true;
1544 case 11: // color by inclination at segment start
1545 for (int ii = 1; ii < (int)myLaneGeometry.getShape().size(); ++ii) {
1546 const double inc = (myLaneGeometry.getShape()[ii].z() - myLaneGeometry.getShape()[ii - 1].z()) / MAX2(POSITION_EPS, myLaneGeometry.getShape()[ii].distanceTo2D(myLaneGeometry.getShape()[ii - 1]));
1547 myShapeColors.push_back(c.getScheme().getColor(inc));
1548 }
1549 col = c.getScheme().getColor(getColorValue(s, 10));
1550 return true;
1551 default:
1552 return false;
1553 }
1554}
1555
1556
1557double
1558GNELane::getColorValue(const GUIVisualizationSettings& s, int activeScheme) const {
1559 const SVCPermissions myPermissions = getParentEdges().front()->getNBEdge()->getPermissions(myIndex);
1560 if (mySpecialColor != nullptr && mySpecialColorValue != std::numeric_limits<double>::max()) {
1561 return mySpecialColorValue;
1562 }
1563 switch (activeScheme) {
1564 case 0:
1565 switch (myPermissions) {
1566 case SVC_PEDESTRIAN:
1567 return 1;
1568 case SVC_BICYCLE:
1569 return 2;
1570 case 0:
1571 // forbidden road or green verge
1572 return getParentEdges().front()->getNBEdge()->getPermissions() == 0 ? 10 : 3;
1573 case SVC_SHIP:
1574 return 4;
1575 case SVC_AUTHORITY:
1576 return 8;
1577 case SVC_AIRCRAFT:
1578 case SVC_DRONE:
1579 return 12;
1580 default:
1581 break;
1582 }
1583 if (getParentEdges().front()->getNBEdge()->isMacroscopicConnector()) {
1584 return 9;
1585 } else if (isRailway(myPermissions)) {
1586 return 5;
1587 } else if ((myPermissions & SVC_PASSENGER) != 0) {
1588 if ((myPermissions & (SVC_RAIL_CLASSES & ~SVC_RAIL_FAST)) != 0 && (myPermissions & SVC_SHIP) == 0) {
1589 return 6;
1590 } else {
1591 return 0;
1592 }
1593 } else {
1594 if ((myPermissions & SVC_RAIL_CLASSES) != 0 && (myPermissions & SVC_SHIP) == 0) {
1595 return 6;
1596 } else {
1597 return 7;
1598 }
1599 }
1600 case 1:
1601 return isAttributeCarrierSelected() || getParentEdges().front()->isAttributeCarrierSelected();
1602 case 2:
1603 return (double)myPermissions;
1604 case 3:
1605 return getParentEdges().front()->getNBEdge()->getLaneSpeed(myIndex);
1606 case 4:
1607 return getParentEdges().front()->getNBEdge()->getNumLanes();
1608 case 5: {
1609 return getParentEdges().front()->getNBEdge()->getLoadedLength() / getParentEdges().front()->getNBEdge()->getLaneStruct(myIndex).shape.length();
1610 }
1611 // case 6: by angle (functional)
1612 case 7: {
1613 return getParentEdges().front()->getNBEdge()->getPriority();
1614 }
1615 case 8: {
1616 // color by z of first shape point
1617 return myLaneGeometry.getShape()[0].z();
1618 }
1619 // case 9: by segment height
1620 case 10: {
1621 // color by incline
1622 return (myLaneGeometry.getShape()[-1].z() - myLaneGeometry.getShape()[0].z()) / getParentEdges().front()->getNBEdge()->getLength();
1623 }
1624 // case 11: by segment incline
1625
1626 case 12: {
1627 // by numerical edge param value
1628 if (getParentEdges().front()->getNBEdge()->hasParameter(s.edgeParam)) {
1629 try {
1630 return StringUtils::toDouble(getParentEdges().front()->getNBEdge()->getParameter(s.edgeParam, "0"));
1631 } catch (NumberFormatException&) {
1632 try {
1633 return StringUtils::toBool(getParentEdges().front()->getNBEdge()->getParameter(s.edgeParam, "0"));
1634 } catch (BoolFormatException&) {
1635 return -1;
1636 }
1637 }
1638 } else {
1640 }
1641 }
1642 case 13: {
1643 // by numerical lane param value
1644 if (getParentEdges().front()->getNBEdge()->getLaneStruct(myIndex).hasParameter(s.laneParam)) {
1645 try {
1646 return StringUtils::toDouble(getParentEdges().front()->getNBEdge()->getLaneStruct(myIndex).getParameter(s.laneParam, "0"));
1647 } catch (NumberFormatException&) {
1648 try {
1649 return StringUtils::toBool(getParentEdges().front()->getNBEdge()->getLaneStruct(myIndex).getParameter(s.laneParam, "0"));
1650 } catch (BoolFormatException&) {
1651 return -1;
1652 }
1653 }
1654 } else {
1656 }
1657 }
1658 case 14: {
1659 return getParentEdges().front()->getNBEdge()->getDistance();
1660 }
1661 case 15: {
1662 return fabs(getParentEdges().front()->getNBEdge()->getDistance());
1663 }
1664 }
1665 return 0;
1666}
1667
1668
1669void
1670GNELane::drawOverlappedRoutes(const int numRoutes) const {
1671 // get middle point and angle
1674 // Push route matrix
1676 // translate to front
1677 glTranslated(0, 0, GLO_ROUTE + 1);
1678 // get middle
1679 GLHelper::drawText(toString(numRoutes) + " routes", center, 0, 1.8, RGBColor::BLACK, angle + 90);
1680 // pop route matrix
1682
1683}
1684
1685
1686void
1688 const auto& laneStopOffset = getParentEdges().front()->getNBEdge()->getLaneStruct(myIndex).laneStopOffset;
1689 // check conditions
1690 if (laneStopOffset.isDefined() && (laneStopOffset.getPermissions() & SVC_PASSENGER) != 0) {
1691 const Position& end = getLaneShape().back();
1692 const Position& f = getLaneShape()[-2];
1693 const double rot = RAD2DEG(atan2((end.x() - f.x()), (f.y() - end.y())));
1696 glTranslated(end.x(), end.y(), 1);
1697 glRotated(rot, 0, 0, 1);
1698 glTranslated(0, laneStopOffset.getOffset(), 0);
1699 glBegin(GL_QUADS);
1700 glVertex2d(-myDrawingConstants->getDrawingWidth(), 0.0);
1701 glVertex2d(-myDrawingConstants->getDrawingWidth(), 0.2);
1702 glVertex2d(myDrawingConstants->getDrawingWidth(), 0.2);
1703 glVertex2d(myDrawingConstants->getDrawingWidth(), 0.0);
1704 glEnd();
1706 }
1707}
1708
1709
1710bool
1712 return isWaterway(getParentEdges().front()->getNBEdge()->getPermissions(myIndex)) && s.showRails; // reusing the showRails setting
1713}
1714
1715
1716void
1718 // Draw direction indicators if the correspondient option is enabled
1719 if (s.showLaneDirection) {
1720 // improve visibility of superposed rail edges
1722 glColor3d(0.3, 0.3, 0.3);
1723 }
1724 // get width and sideOffset
1725 const double width = MAX2(NUMERICAL_EPS, (myDrawingConstants->getDrawingWidth() * 2 * myDrawingConstants->getExaggeration()));
1726 // push direction indicator matrix
1728 // move to front
1729 glTranslated(0, 0, 0.1);
1730 // iterate over shape
1731 for (int i = 0; i < (int) myLaneGeometry.getShape().size() - 1; ++i) {
1732 // push triangle matrix
1734 // move front
1735 glTranslated(myLaneGeometry.getShape()[i].x(), myLaneGeometry.getShape()[i].y(), 0.1);
1736 // rotate
1737 glRotated(myLaneGeometry.getShapeRotations()[i], 0, 0, 1);
1738 // calculate subwidth
1739 for (double subWidth = 0; subWidth < myLaneGeometry.getShapeLengths()[i]; subWidth += width) {
1740 // calculate length
1741 const double length = MIN2(width * 0.5, myLaneGeometry.getShapeLengths()[i] - subWidth);
1742 // draw triangle
1743 glBegin(GL_TRIANGLES);
1744 glVertex2d(-myDrawingConstants->getOffset(), -subWidth - length);
1745 glVertex2d(-myDrawingConstants->getOffset() - width * 0.25, -subWidth);
1746 glVertex2d(-myDrawingConstants->getOffset() + width * 0.25, -subWidth);
1747 glEnd();
1748 }
1749 // pop triangle matrix
1751 }
1752 // pop direction indicator matrix
1754 }
1755}
1756
1757
1758void
1760 // draw foot width 150mm, assume that distance between rail feet inner sides is reduced on both sides by 39mm with regard to the gauge
1761 // assume crosstie length of 181% gauge (2600mm for standard gauge)
1762 // first save current color (obtained from view configuration)
1763 const auto currentLaneColor = GLHelper::getColor();
1764 // Set current color
1765 GLHelper::setColor(currentLaneColor);
1766 // continue depending of detail
1768 // move
1769 glTranslated(0, 0, 0.1);
1770 // draw external crossbar
1771 const double crossbarWidth = 0.2 * myDrawingConstants->getExaggeration();
1772 // draw geometry
1776 // move
1777 glTranslated(0, 0, 0.01);
1778 // Set color gray
1779 glColor3d(0.8, 0.8, 0.8);
1780 // draw geometry
1784 // move
1785 glTranslated(0, 0, 0.01);
1786 // Set current color
1787 GLHelper::setColor(currentLaneColor);
1788 // Draw crossties
1791 myDrawingConstants->getOffset(), false);
1792 } else if (myShapeColors.size() > 0) {
1793 // draw colored box lines
1796 } else {
1797 // draw geometry with current color
1800 }
1801}
1802
1803
1804void
1806 // check all conditions for drawing textures
1807 if (!s.disableLaneIcons && (myLaneRestrictedTexturePositions.size() > 0)) {
1808 // Declare default width of icon (3)
1809 const double iconWidth = myDrawingConstants->getDrawingWidth() * 0.6;
1810 // Draw list of icons
1811 for (int i = 0; i < (int)myLaneRestrictedTexturePositions.size(); i++) {
1812 // Push draw matrix 2
1814 // Set white color
1815 glColor3d(1, 1, 1);
1816 // Translate matrix 2
1817 glTranslated(myLaneRestrictedTexturePositions.at(i).x(), myLaneRestrictedTexturePositions.at(i).y(), 0.1);
1818 // Rotate matrix 2
1819 glRotated(myLaneRestrictedTextureRotations.at(i), 0, 0, -1);
1820 glRotated(90, 0, 0, 1);
1821 // draw texture box depending of type of restriction
1824 } else if (isRestricted(SVC_BICYCLE)) {
1826 } else if (isRestricted(SVC_BUS)) {
1828 }
1829 // Pop draw matrix 2
1831 }
1832 }
1833}
1834
1835
1836void
1838 // draw a Start/endPoints if lane has a custom shape
1839 if ((myDrawingConstants->getDetail() <= GUIVisualizationSettings::Detail::GeometryPoint) && (getParentEdges().front()->getNBEdge()->getLaneStruct(myIndex).customShape.size() > 1)) {
1840 // obtain circle width and resolution
1841 const double circleWidth = GNEEdge::SNAP_RADIUS * MIN2((double)1, s.laneWidthExaggeration) / 2;
1842 // obtain custom shape
1843 const PositionVector& customShape = getParentEdges().front()->getNBEdge()->getLaneStruct(myIndex).customShape;
1844 // set color (override with special colors unless the color scheme is based on selection)
1845 if (drawUsingSelectColor() && s.laneColorer.getActive() != 1) {
1847 } else {
1848 GLHelper::setColor(s.junctionColorer.getSchemes()[0].getColor(2));
1849 }
1850 // push start matrix
1852 // move to shape start position
1853 glTranslated(customShape.front().x(), customShape.front().y(), 0.1);
1854 // draw circle
1856 // draw s depending of detail
1858 // move top
1859 glTranslated(0, 0, 0.1);
1860 // draw "S"
1861 GLHelper::drawText("S", Position(), 0.1, circleWidth, RGBColor::WHITE);
1862 }
1863 // pop start matrix
1865 // draw line between junction and start position
1867 // move top
1868 glTranslated(0, 0, 0.1);
1869 // set line width
1870 glLineWidth(4);
1871 // draw line
1872 GLHelper::drawLine(customShape.front(), getParentEdges().front()->getFromJunction()->getPositionInView());
1873 // pop line matrix
1875 // push start matrix
1877 // move to end position
1878 glTranslated(customShape.back().x(), customShape.back().y(), 0.1);
1879 // draw filled circle
1881 // draw "e" depending of detail
1883 // move top
1884 glTranslated(0, 0, 0.1);
1885 // draw "E"
1886 GLHelper::drawText("E", Position(), 0, circleWidth, RGBColor::WHITE);
1887 }
1888 // pop start matrix
1890 // draw line between Junction and end position
1892 // move top
1893 glTranslated(0, 0, 0.1);
1894 // set line width
1895 glLineWidth(4);
1896 // draw line
1897 GLHelper::drawLine(customShape.back(), getParentEdges().front()->getToJunction()->getPositionInView());
1898 // pop line matrix
1900 }
1901}
1902
1903
1904bool
1906 return setLaneColor(s).alpha() != 0;
1907}
1908
1909
1910std::string
1912 return getParentEdges().front()->getID();
1913}
1914
1915
1916long
1917GNELane::onDefault(FXObject* obj, FXSelector sel, void* data) {
1918 myNet->getViewParent()->getTLSEditorFrame()->handleMultiChange(this, obj, sel, data);
1919 return 1;
1920}
1921
1922
1923std::vector<GNEConnection*>
1925 // Declare a vector to save incoming connections
1926 std::vector<GNEConnection*> incomingConnections;
1927 // Obtain incoming edges if junction source was already created
1928 GNEJunction* junctionSource = getParentEdges().front()->getFromJunction();
1929 if (junctionSource) {
1930 // Iterate over incoming GNEEdges of junction
1931 for (const auto& incomingEdge : junctionSource->getGNEIncomingEdges()) {
1932 // Iterate over connection of incoming edges
1933 for (const auto& connection : incomingEdge->getGNEConnections()) {
1934 if (connection->getLaneTo()->getIndex() == getIndex()) {
1935 incomingConnections.push_back(connection);
1936 }
1937 }
1938 }
1939 }
1940 return incomingConnections;
1941}
1942
1943
1944std::vector<GNEConnection*>
1946 // Obtain GNEConnection of parent edge
1947 const std::vector<GNEConnection*>& edgeConnections = getParentEdges().front()->getGNEConnections();
1948 std::vector<GNEConnection*> outcomingConnections;
1949 // Obtain outgoing connections
1950 for (const auto& connection : edgeConnections) {
1951 if (connection->getLaneFrom()->getIndex() == getIndex()) {
1952 outcomingConnections.push_back(connection);
1953 }
1954 }
1955 return outcomingConnections;
1956}
1957
1958
1959void
1961 // update incoming connections of lane
1962 std::vector<GNEConnection*> incomingConnections = getGNEIncomingConnections();
1963 for (const auto& incomingConnection : incomingConnections) {
1964 incomingConnection->updateConnectionID();
1965 }
1966 // update outcoming connections of lane
1967 std::vector<GNEConnection*> outcomingConnections = getGNEOutcomingConnections();
1968 for (const auto& outcomingConnection : outcomingConnections) {
1969 outcomingConnection->updateConnectionID();
1970 }
1971}
1972
1973
1974double
1976 // factor should not be 0
1977 if (getParentEdges().front()->getNBEdge()->getFinalLength() > 0) {
1978 return MAX2(POSITION_EPS, (getLaneShape().length() / getParentEdges().front()->getNBEdge()->getFinalLength()));
1979 } else {
1980 return POSITION_EPS;
1981 };
1982}
1983
1984
1985void
1987 // Create basic commands
1988 std::string edgeDescPossibleMulti = toString(SUMO_TAG_EDGE);
1989 const int edgeSelSize = getParentEdges().front()->isAttributeCarrierSelected() ? myNet->getAttributeCarriers()->getNumberOfSelectedEdges() : 0;
1990 if (edgeSelSize && getParentEdges().front()->isAttributeCarrierSelected() && (edgeSelSize > 1)) {
1991 edgeDescPossibleMulti = toString(edgeSelSize) + " " + toString(SUMO_TAG_EDGE) + "s";
1992 }
1993 // create menu pane for edge operations
1994 FXMenuPane* edgeOperations = new FXMenuPane(ret);
1995 ret->insertMenuPaneChild(edgeOperations);
1996 if (edgeSelSize > 0) {
1997 new FXMenuCascade(ret, TLF("Edge operations (% selected)", toString(edgeSelSize)).c_str(), nullptr, edgeOperations);
1998 } else {
1999 new FXMenuCascade(ret, TL("Edge operations"), nullptr, edgeOperations);
2000 }
2001 // create menu commands for all edge operations
2002 GUIDesigns::buildFXMenuCommand(edgeOperations, TL("Split edge here"), nullptr, &parent, MID_GNE_EDGE_SPLIT);
2003 auto splitBothDirections = GUIDesigns::buildFXMenuCommand(edgeOperations, TL("Split edge in both directions here (no symmetric opposite edge)"), nullptr, &parent, MID_GNE_EDGE_SPLIT_BIDI);
2004 // check if allow split edge in both directions
2005 splitBothDirections->disable();
2006 const auto oppositeEdges = getParentEdges().front()->getOppositeEdges();
2007 if (oppositeEdges.size() == 0) {
2008 splitBothDirections->setText(TL("Split edge in both directions here (no opposite edge)"));
2009 } else {
2010 for (const auto& oppositeEdge : oppositeEdges) {
2011 // get reverse inner geometry
2012 const auto reverseGeometry = oppositeEdge->getNBEdge()->getInnerGeometry().reverse();
2013 if (reverseGeometry == getParentEdges().front()->getNBEdge()->getInnerGeometry()) {
2014 splitBothDirections->enable();
2015 splitBothDirections->setText(TL("Split edge in both directions here"));
2016 }
2017 }
2018 }
2019 GUIDesigns::buildFXMenuCommand(edgeOperations, TL("Set geometry endpoint here (shift-click)"), nullptr, &parent, MID_GNE_EDGE_EDIT_ENDPOINT);
2020 // restore geometry points depending of selection status
2021 if (getParentEdges().front()->isAttributeCarrierSelected()) {
2022 if (edgeSelSize == 1) {
2023 GUIDesigns::buildFXMenuCommand(edgeOperations, TL("Restore both geometry endpoints"), nullptr, &parent, MID_GNE_EDGE_RESET_ENDPOINT);
2024 } else {
2025 GUIDesigns::buildFXMenuCommand(edgeOperations, TL("Restore geometry endpoints of all selected edges"), nullptr, &parent, MID_GNE_EDGE_RESET_ENDPOINT);
2026 }
2027 } else {
2028 GUIDesigns::buildFXMenuCommand(edgeOperations, TL("Restore geometry endpoint (shift-click)"), nullptr, &parent, MID_GNE_EDGE_RESET_ENDPOINT);
2029 }
2030 GUIDesigns::buildFXMenuCommand(edgeOperations, TLF("Reverse %", edgeDescPossibleMulti), nullptr, &parent, MID_GNE_EDGE_REVERSE);
2031 auto reverse = GUIDesigns::buildFXMenuCommand(edgeOperations, TLF("Add reverse direction for %", edgeDescPossibleMulti), nullptr, &parent, MID_GNE_EDGE_ADD_REVERSE);
2032 if (getParentEdges().front()->getReverseEdge() != nullptr) {
2033 reverse->disable();
2034 }
2035 GUIDesigns::buildFXMenuCommand(edgeOperations, TLF("Add reverse disconnected direction for %", edgeDescPossibleMulti), nullptr, &parent, MID_GNE_EDGE_ADD_REVERSE_DISCONNECTED);
2036 GUIDesigns::buildFXMenuCommand(edgeOperations, TLF("Reset lengths for %", edgeDescPossibleMulti), nullptr, &parent, MID_GNE_EDGE_RESET_LENGTH);
2037 GUIDesigns::buildFXMenuCommand(edgeOperations, TLF("Straighten %", edgeDescPossibleMulti), nullptr, &parent, MID_GNE_EDGE_STRAIGHTEN);
2038 GUIDesigns::buildFXMenuCommand(edgeOperations, TLF("Smooth %", edgeDescPossibleMulti), nullptr, &parent, MID_GNE_EDGE_SMOOTH);
2039 GUIDesigns::buildFXMenuCommand(edgeOperations, TLF("Straighten elevation of %", edgeDescPossibleMulti), nullptr, &parent, MID_GNE_EDGE_STRAIGHTEN_ELEVATION);
2040 GUIDesigns::buildFXMenuCommand(edgeOperations, TLF("Smooth elevation of %", edgeDescPossibleMulti), nullptr, &parent, MID_GNE_EDGE_SMOOTH_ELEVATION);
2041}
2042
2043
2044void
2046 // Get icons
2047 FXIcon* pedestrianIcon = GUIIconSubSys::getIcon(GUIIcon::LANE_PEDESTRIAN);
2048 FXIcon* bikeIcon = GUIIconSubSys::getIcon(GUIIcon::LANE_BIKE);
2049 FXIcon* busIcon = GUIIconSubSys::getIcon(GUIIcon::LANE_BUS);
2050 FXIcon* greenVergeIcon = GUIIconSubSys::getIcon(GUIIcon::LANEGREENVERGE);
2051 // declare number of selected lanes
2052 int numSelectedLanes = 0;
2053 // if lane is selected, calculate number of restricted lanes
2054 bool edgeHasSidewalk = false;
2055 bool edgeHasBikelane = false;
2056 bool edgeHasBuslane = false;
2057 bool differentLaneShapes = false;
2059 const auto selectedLanes = myNet->getAttributeCarriers()->getSelectedLanes();
2060 // update numSelectedLanes
2061 numSelectedLanes = (int)selectedLanes.size();
2062 // iterate over selected lanes
2063 for (const auto& selectedLane : selectedLanes) {
2064 if (selectedLane->getParentEdges().front()->hasRestrictedLane(SVC_PEDESTRIAN)) {
2065 edgeHasSidewalk = true;
2066 }
2067 if (selectedLane->getParentEdges().front()->hasRestrictedLane(SVC_BICYCLE)) {
2068 edgeHasBikelane = true;
2069 }
2070 if (selectedLane->getParentEdges().front()->hasRestrictedLane(SVC_BUS)) {
2071 edgeHasBuslane = true;
2072 }
2073 if (selectedLane->getParentEdges().front()->getNBEdge()->getLaneStruct(selectedLane->getIndex()).customShape.size() != 0) {
2074 differentLaneShapes = true;
2075 }
2076 }
2077 } else {
2078 edgeHasSidewalk = getParentEdges().front()->hasRestrictedLane(SVC_PEDESTRIAN);
2079 edgeHasBikelane = getParentEdges().front()->hasRestrictedLane(SVC_BICYCLE);
2080 edgeHasBuslane = getParentEdges().front()->hasRestrictedLane(SVC_BUS);
2081 differentLaneShapes = getParentEdges().front()->getNBEdge()->getLaneStruct(myIndex).customShape.size() != 0;
2082 }
2083 // create menu pane for lane operations
2084 FXMenuPane* laneOperations = new FXMenuPane(ret);
2085 ret->insertMenuPaneChild(laneOperations);
2086 if (numSelectedLanes > 0) {
2087 new FXMenuCascade(ret, TLF("Lane operations (% selected)", toString(numSelectedLanes)).c_str(), nullptr, laneOperations);
2088 } else {
2089 new FXMenuCascade(ret, TL("Lane operations"), nullptr, laneOperations);
2090 }
2091 GUIDesigns::buildFXMenuCommand(laneOperations, TL("Duplicate lane"), nullptr, &parent, MID_GNE_LANE_DUPLICATE);
2092 GUIDesigns::buildFXMenuCommand(laneOperations, TL("Set custom lane shape"), nullptr, &parent, MID_GNE_LANE_EDIT_SHAPE);
2093 FXMenuCommand* resetCustomShape = GUIDesigns::buildFXMenuCommand(laneOperations, TL("Reset custom shape"), nullptr, &parent, MID_GNE_LANE_RESET_CUSTOMSHAPE);
2094 if (!differentLaneShapes) {
2095 resetCustomShape->disable();
2096 }
2097 FXMenuCommand* resetOppositeLane = GUIDesigns::buildFXMenuCommand(laneOperations, TL("Reset opposite lane"), nullptr, &parent, MID_GNE_LANE_RESET_OPPOSITELANE);
2098 if (getAttribute(GNE_ATTR_OPPOSITE).empty()) {
2099 resetOppositeLane->disable();
2100 }
2101 // Create panel for lane operations and insert it in ret
2102 FXMenuPane* addSpecialLanes = new FXMenuPane(laneOperations);
2103 ret->insertMenuPaneChild(addSpecialLanes);
2104 FXMenuPane* removeSpecialLanes = new FXMenuPane(laneOperations);
2105 ret->insertMenuPaneChild(removeSpecialLanes);
2106 FXMenuPane* transformSlanes = new FXMenuPane(laneOperations);
2107 ret->insertMenuPaneChild(transformSlanes);
2108 // Create menu comands for all add special lanes
2109 FXMenuCommand* addSidewalk = GUIDesigns::buildFXMenuCommand(addSpecialLanes, TL("Sidewalk"), pedestrianIcon, &parent, MID_GNE_LANE_ADD_SIDEWALK);
2110 FXMenuCommand* addBikelane = GUIDesigns::buildFXMenuCommand(addSpecialLanes, TL("Bike lane"), bikeIcon, &parent, MID_GNE_LANE_ADD_BIKE);
2111 FXMenuCommand* addBuslane = GUIDesigns::buildFXMenuCommand(addSpecialLanes, TL("Bus lane"), busIcon, &parent, MID_GNE_LANE_ADD_BUS);
2112 // if parent edge is selected, always add greenverge in front
2113 if (getParentEdges().front()->isAttributeCarrierSelected()) {
2114 GUIDesigns::buildFXMenuCommand(addSpecialLanes, TL("Green verge"), greenVergeIcon, &parent, MID_GNE_LANE_ADD_GREENVERGE_FRONT);
2115 } else {
2116 GUIDesigns::buildFXMenuCommand(addSpecialLanes, TL("Green verge (front)"), greenVergeIcon, &parent, MID_GNE_LANE_ADD_GREENVERGE_FRONT);
2117 GUIDesigns::buildFXMenuCommand(addSpecialLanes, TL("Green verge (back)"), greenVergeIcon, &parent, MID_GNE_LANE_ADD_GREENVERGE_BACK);
2118 }
2119 // Create menu comands for all remove special lanes and disable it
2120 FXMenuCommand* removeSidewalk = GUIDesigns::buildFXMenuCommand(removeSpecialLanes, TL("Sidewalk"), pedestrianIcon, &parent, MID_GNE_LANE_REMOVE_SIDEWALK);
2121 removeSidewalk->disable();
2122 FXMenuCommand* removeBikelane = GUIDesigns::buildFXMenuCommand(removeSpecialLanes, TL("Bike lane"), bikeIcon, &parent, MID_GNE_LANE_REMOVE_BIKE);
2123 removeBikelane->disable();
2124 FXMenuCommand* removeBuslane = GUIDesigns::buildFXMenuCommand(removeSpecialLanes, TL("Bus lane"), busIcon, &parent, MID_GNE_LANE_REMOVE_BUS);
2125 removeBuslane->disable();
2126 FXMenuCommand* removeGreenVerge = GUIDesigns::buildFXMenuCommand(removeSpecialLanes, TL("Green verge"), greenVergeIcon, &parent, MID_GNE_LANE_REMOVE_GREENVERGE);
2127 removeGreenVerge->disable();
2128 // Create menu comands for all transform special lanes and disable it
2129 FXMenuCommand* transformLaneToSidewalk = GUIDesigns::buildFXMenuCommand(transformSlanes, TL("Sidewalk"), pedestrianIcon, &parent, MID_GNE_LANE_TRANSFORM_SIDEWALK);
2130 FXMenuCommand* transformLaneToBikelane = GUIDesigns::buildFXMenuCommand(transformSlanes, TL("Bike lane"), bikeIcon, &parent, MID_GNE_LANE_TRANSFORM_BIKE);
2131 FXMenuCommand* transformLaneToBuslane = GUIDesigns::buildFXMenuCommand(transformSlanes, TL("Bus lane"), busIcon, &parent, MID_GNE_LANE_TRANSFORM_BUS);
2132 FXMenuCommand* transformLaneToGreenVerge = GUIDesigns::buildFXMenuCommand(transformSlanes, TL("Green verge"), greenVergeIcon, &parent, MID_GNE_LANE_TRANSFORM_GREENVERGE);
2133 // add menuCascade for lane operations
2134 new FXMenuCascade(laneOperations, TLF("Add restricted %", toString(SUMO_TAG_LANE)).c_str(), nullptr, addSpecialLanes);
2135 FXMenuCascade* cascadeRemoveSpecialLane = new FXMenuCascade(laneOperations, TLF("Remove restricted %", toString(SUMO_TAG_LANE)).c_str(), nullptr, removeSpecialLanes);
2136 new FXMenuCascade(laneOperations, TLF("Transform to restricted %", toString(SUMO_TAG_LANE)).c_str(), nullptr, transformSlanes);
2137 // Enable and disable options depending of current transform of the lane
2138 if (edgeHasSidewalk) {
2139 transformLaneToSidewalk->disable();
2140 addSidewalk->disable();
2141 removeSidewalk->enable();
2142 }
2143 if (edgeHasBikelane) {
2144 transformLaneToBikelane->disable();
2145 addBikelane->disable();
2146 removeBikelane->enable();
2147 }
2148 if (edgeHasBuslane) {
2149 transformLaneToBuslane->disable();
2150 addBuslane->disable();
2151 removeBuslane->enable();
2152 }
2154 transformLaneToGreenVerge->disable();
2155 removeGreenVerge->enable();
2156 }
2157 // Check if cascade menu must be disabled
2158 if (!edgeHasSidewalk && !edgeHasBikelane && !edgeHasBuslane && !isRestricted(SVC_IGNORING)) {
2159 cascadeRemoveSpecialLane->disable();
2160 }
2161 // for whatever reason, sonar complains in the next line that cascadeRemoveSpecialLane may leak, but fox does the cleanup
2162} // NOSONAR
2163
2164
2165void
2167 // Create basic commands
2168 std::string edgeDescPossibleMulti = toString(SUMO_TAG_EDGE);
2169 const int numSelectedEdges = getParentEdges().front()->isAttributeCarrierSelected() ? myNet->getAttributeCarriers()->getNumberOfSelectedEdges() : 0;
2170 if ((numSelectedEdges > 0) && getParentEdges().front()->isAttributeCarrierSelected() && (numSelectedEdges > 1)) {
2171 edgeDescPossibleMulti = toString(numSelectedEdges) + " " + toString(SUMO_TAG_EDGE) + "s";
2172 }
2173 // create menu pane for edge operations
2174 FXMenuPane* edgeOperations = new FXMenuPane(ret);
2175 ret->insertMenuPaneChild(edgeOperations);
2176 if (numSelectedEdges > 0) {
2177 new FXMenuCascade(ret, TLF("Template operations (% selected)", toString(numSelectedEdges)).c_str(), nullptr, edgeOperations);
2178 } else {
2179 new FXMenuCascade(ret, TL("Template operations"), nullptr, edgeOperations);
2180 }
2181 // create menu commands for all edge operations
2182 GUIDesigns::buildFXMenuCommand(edgeOperations, TL("Use edge as template"), nullptr, &parent, MID_GNE_EDGE_USEASTEMPLATE);
2183 auto applyTemplate = GUIDesigns::buildFXMenuCommand(edgeOperations, TL("Apply template"), nullptr, &parent, MID_GNE_EDGE_APPLYTEMPLATE);
2184 // check if disable apply template
2186 applyTemplate->disable();
2187 }
2188}
2189
2190
2191void
2193 // addreachability menu
2194 FXMenuPane* reachableByClass = new FXMenuPane(ret);
2195 ret->insertMenuPaneChild(reachableByClass);
2196 if (myNet->isNetRecomputed()) {
2197 new FXMenuCascade(ret, TL("Select reachable"), GUIIconSubSys::getIcon(GUIIcon::MODEVEHICLE), reachableByClass);
2198 for (const auto& vClass : SumoVehicleClassStrings.getStrings()) {
2199 GUIDesigns::buildFXMenuCommand(reachableByClass, vClass.c_str(), VClassIcons::getVClassIcon(SumoVehicleClassStrings.get(vClass)), &parent, MID_REACHABILITY);
2200 }
2201 } else {
2202 FXMenuCommand* menuCommand = GUIDesigns::buildFXMenuCommand(ret, TL("Select reachable (compute junctions)"), nullptr, nullptr, 0);
2203 menuCommand->handle(&parent, FXSEL(SEL_COMMAND, FXWindow::ID_DISABLE), nullptr);
2204 }
2205}
2206
2207/****************************************************************************/
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:861
@ 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:487
@ MID_GNE_LANE_ADD_BUS
add busLane
@ MID_GNE_REMOVESELECT_EDGE
Remove edge from selected items - Menu Entry.
Definition GUIAppEnum.h:863
@ MID_GNE_EDGE_STRAIGHTEN_ELEVATION
interpolate z values linear between junctions
@ MID_GNE_EDGE_SMOOTH
smooth geometry
@ MID_GNE_LANE_RESET_CUSTOMSHAPE
reset custom shape
@ MID_GNE_EDGE_STRAIGHTEN
remove inner geometry
@ MID_GNE_LANE_TRANSFORM_BUS
transform lane to busLane
@ MID_COPY_EDGE_NAME
Copy edge name (for lanes only)
Definition GUIAppEnum.h:461
@ 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:533
@ MID_GNE_EDGE_RESET_LENGTH
reset custom lengths
@ MID_GNE_LANE_REMOVE_BUS
remove busLane
@ MID_GNE_LANE_REMOVE_SIDEWALK
remove sidewalk
@ MID_GNE_EDGE_RESET_ENDPOINT
reset default geometry endpoints
@ MID_GNE_LANE_ADD_GREENVERGE_BACK
add greenVerge back of current lane
@ MID_GNE_EDGE_SMOOTH_ELEVATION
smooth elevation with regard to adjoining edges
@ MID_GNE_EDGE_ADD_REVERSE
add reverse edge
@ MID_GNE_EDGE_APPLYTEMPLATE
apply template
@ MID_GNE_EDGE_USEASTEMPLATE
use edge as tempalte
@ MID_GNE_LANE_ADD_SIDEWALK
add sidewalk
@ MID_GNE_RESET_GEOMETRYPOINT
reset geometry point
@ MID_GNE_LANE_TRANSFORM_SIDEWALK
transform lane to sidewalk
@ MID_GNE_LANE_ADD_BIKE
add bikelane
@ MID_GNE_EDGE_SPLIT
split an edge
@ MID_GNE_LANE_TRANSFORM_GREENVERGE
transform lane to greenVerge
@ MID_GNE_CUSTOM_GEOMETRYPOINT
set custom geometry point
@ MID_GNE_EDGE_EDIT_ENDPOINT
change default geometry endpoints
@ MID_REMOVESELECT
Remove from selected items - Menu Entry.
Definition GUIAppEnum.h:489
@ 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_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
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:232
bool isAttributeComputed(SumoXMLAttr key) const override
Definition GNELane.cpp:875
const GNELane2laneConnection & getLane2laneConnections() const
get Lane2laneConnection struct
Definition GNELane.cpp:667
~GNELane()
Destructor.
Definition GNELane.cpp:188
double getColorValue(const GUIVisualizationSettings &s, int activeScheme) const override
return value for lane coloring according to the given scheme
Definition GNELane.cpp:1558
void drawLaneStopOffset(const GUIVisualizationSettings &s) const
draw laneStopOffset
Definition GNELane.cpp:1687
void drawSelectedLane(const GUIVisualizationSettings &s) const
draw selected lane
Definition GNELane.cpp:1047
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:220
void drawMarkingsAndBoundings(const GUIVisualizationSettings &s) const
draw lane markings
Definition GNELane.cpp:1113
bool checkDrawSelectContour() const override
check if draw select contour (blue)
Definition GNELane.cpp:424
const RGBColor * mySpecialColor
optional special color
Definition GNELane.h:378
Position getPositionInView() const
Returns position of hierarchical element in view.
Definition GNELane.cpp:338
bool drawAsWaterway(const GUIVisualizationSettings &s) const
whether to draw this lane as a waterways
Definition GNELane.cpp:1711
Boundary getCenteringBoundary() const override
Returns the boundary to which the view shall be centered in order to show the object.
Definition GNELane.cpp:613
double getLengthGeometryFactor() const
get length geometry factor
Definition GNELane.cpp:1975
PositionVector getAttributePositionVector(SumoXMLAttr key) const override
Definition GNELane.cpp:742
void drawDirectionIndicators(const GUIVisualizationSettings &s) const
direction indicators for lanes
Definition GNELane.cpp:1717
bool checkDrawOverContour() const override
check if draw over contour (orange)
Definition GNELane.cpp:380
int getIndex() const
returns the index of the lane
Definition GNELane.cpp:625
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:1066
void drawOverlappedRoutes(const int numRoutes) const
draw overlapped routes
Definition GNELane.cpp:1670
bool checkDrawRelatedContour() const override
check if draw related contour (cyan)
Definition GNELane.cpp:370
GUIGLObjectPopupMenu * getPopUpMenu(GUIMainWindow &app, GUISUMOAbstractView &parent) override
Returns an own popup-menu.
Definition GNELane.cpp:497
bool checkDrawToContour() const override
check if draw from contour (magenta)
Definition GNELane.cpp:357
std::string getParentName() const override
Returns the name of the parent object (if any)
Definition GNELane.cpp:1911
void buildLaneOperations(GUISUMOAbstractView &parent, GUIGLObjectPopupMenu *ret)
build lane operations contextual menu
Definition GNELane.cpp:2045
GNEMoveElement * getMoveElement() const override
methods to retrieve the elements linked to this lane
Definition GNELane.cpp:196
GNELane()
FOX needs this.
Definition GNELane.cpp:175
std::vector< GNEConnection * > getGNEOutcomingConnections()
returns a vector with the outgoing GNEConnections of this lane
Definition GNELane.cpp:1945
DrawingConstants * myDrawingConstants
LaneDrawingConstants.
Definition GNELane.h:365
const std::vector< double > & getShapeRotations() const
get rotations of the single shape parts
Definition GNELane.cpp:242
std::string getAttributeForSelection(SumoXMLAttr key) const override
method for getting the attribute in the context of object selection
Definition GNELane.cpp:754
void buildTemplateOperations(GUISUMOAbstractView &parent, GUIGLObjectPopupMenu *ret)
build template oerations contextual menu
Definition GNELane.cpp:2166
double getExaggeration(const GUIVisualizationSettings &s) const override
return exaggeration associated with this GLObject
Definition GNELane.cpp:607
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:1534
void calculateLaneContour(const GUIVisualizationSettings &s, const double layer) const
calculate contour
Definition GNELane.cpp:1406
void drawTLSLinkNo(const GUIVisualizationSettings &s) const
draw TLS link Number
Definition GNELane.cpp:1231
double getLaneParametricLength() const
returns the parameteric length of the lane
Definition GNELane.cpp:644
RGBColor setLaneColor(const GUIVisualizationSettings &s) const
set color according to edit mode and visualisation settings
Definition GNELane.cpp:1424
std::vector< GNEConnection * > getGNEIncomingConnections()
returns a vector with the incoming GNEConnections of this lane
Definition GNELane.cpp:1924
void updateGeometry() override
update pre-computed geometry information
Definition GNELane.cpp:260
bool isRestricted(SUMOVehicleClass vclass) const
check if this lane is restricted
Definition GNELane.cpp:661
bool checkDrawFromContour() const override
check if draw from contour (green)
Definition GNELane.cpp:344
const DrawingConstants * getDrawingConstants() const
get lane drawing constants (previously calculated in drawGL())
Definition GNELane.cpp:254
int myIndex
The index of this lane.
Definition GNELane.h:359
void drawLaneAsRailway() const
draw lane as railway
Definition GNELane.cpp:1759
std::string getAttribute(SumoXMLAttr key) const override
Definition GNELane.cpp:673
void setIndex(int index)
Definition GNELane.cpp:631
void setSpecialColor(const RGBColor *Color2, double colorValue=std::numeric_limits< double >::max())
Definition GNELane.cpp:887
void drawGL(const GUIVisualizationSettings &s) const override
Draws the object.
Definition GNELane.cpp:454
const GUIGeometry & getLaneGeometry() const
get lane geometry
Definition GNELane.cpp:226
bool checkDrawMoveContour() const override
check if draw move contour (red)
Definition GNELane.cpp:442
Position getAttributePosition(SumoXMLAttr key) const override
Definition GNELane.cpp:736
double getAttributeDouble(SumoXMLAttr key) const override
Definition GNELane.cpp:730
void setAttribute(SumoXMLAttr key, const std::string &value, GNEUndoList *undoList) override
Definition GNELane.cpp:764
void drawArrows(const GUIVisualizationSettings &s) const
draw lane arrows
Definition GNELane.cpp:1268
void updateCenteringBoundary(const bool updateGrid)
update centering boundary (implies change in RTREE)
Definition GNELane.cpp:619
void drawLane(const GUIVisualizationSettings &s, const double layer) const
draw lane
Definition GNELane.cpp:990
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:1092
Parameterised * getParameters() override
get parameters associated with this lane
Definition GNELane.cpp:202
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:1917
bool checkDrawDeleteContour() const override
check if draw delete contour (pink/white)
Definition GNELane.cpp:400
double getLaneShapeLength() const
returns the length of the lane's shape
Definition GNELane.cpp:655
void updateGLObject() override
update GLObject (geometry, ID, etc.)
Definition GNELane.cpp:490
void drawStartEndGeometryPoints(const GUIVisualizationSettings &s) const
draw start and end geometry points
Definition GNELane.cpp:1837
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:418
bool setFunctionalColor(int activeScheme, RGBColor &col) const
sets the color according to the current scheme index and some lane function
Definition GNELane.cpp:1520
bool isVisible(const GUIVisualizationSettings &s) const override
check if object is visible (Currently used only in netedit)
Definition GNELane.cpp:1905
void updateConnectionIDs()
update IDs of incoming connections of this lane
Definition GNELane.cpp:1960
void buildRechableOperations(GUISUMOAbstractView &parent, GUIGLObjectPopupMenu *ret)
build rechable operations contextual menu
Definition GNELane.cpp:2192
bool isValid(SumoXMLAttr key, const std::string &value) override
Definition GNELane.cpp:800
bool isAttributeEnabled(SumoXMLAttr key) const override
Definition GNELane.cpp:861
void drawLane2LaneConnections() const
draw lane to lane connections
Definition GNELane.cpp:1358
void buildEdgeOperations(GUISUMOAbstractView &parent, GUIGLObjectPopupMenu *ret)
build edge operations contextual menu
Definition GNELane.cpp:1986
const std::vector< double > & getShapeLengths() const
get lengths of the single shape parts
Definition GNELane.cpp:248
void drawLinkNo(const GUIVisualizationSettings &s) const
draw link Number
Definition GNELane.cpp:1194
double getSpeed() const
returns the current speed of lane
Definition GNELane.cpp:638
void drawTextures(const GUIVisualizationSettings &s) const
draw lane textures
Definition GNELane.cpp:1805
void deleteGLObject() override
delete element
Definition GNELane.cpp:481
GNEEdge * getParentEdge() const
get parent edge
Definition GNELane.cpp:214
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
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
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
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 buildShowParamsPopupEntry(GUIGLObjectPopupMenu *ret, bool addSeparator=true)
Builds an entry which allows to open the parameter window.
void buildCenterPopupEntry(GUIGLObjectPopupMenu *ret, bool addSeparator=true)
Builds an entry which allows to center to the object.
void buildNameCopyPopupEntry(GUIGLObjectPopupMenu *ret, bool addSeparator=true)
Builds entries which allow to copy the name / typed name into the clipboard.
void buildPopupHeader(GUIGLObjectPopupMenu *ret, GUIMainWindow &app, bool addSeparator=true)
Builds the header.
GUIGlObjectType getType() const
Returns the type of the object as coded in GUIGlObjectType.
static FXIcon * getIcon(const GUIIcon which)
returns a icon previously defined in the enum GUIIcon
T getColor(const double value) const
const std::vector< T > & getSchemes() const
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
LinkState getLinkState(const NBEdge *incoming, const NBEdge *outgoing, int fromLane, int toLane, bool mayDefinitelyPass, const std::string &tlID) const
get link state
Definition NBNode.cpp:2592
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:205
unsigned char alpha() const
Returns the alpha-amount of the color.
Definition RGBColor.cpp:96
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:413
static const RGBColor ORANGE
Definition RGBColor.h:204
static const RGBColor CYAN
Definition RGBColor.h:202
static const RGBColor GREEN
Definition RGBColor.h:199
static const RGBColor BLACK
Definition RGBColor.h:206
RGBColor changedBrightness(int change, int toChange=3) const
Returns a new color with altered brightness.
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
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