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