Eclipse SUMO - Simulation of Urban MObility
Loading...
Searching...
No Matches
GNEEdge.cpp
Go to the documentation of this file.
1/****************************************************************************/
2// Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.dev/sumo
3// Copyright (C) 2001-2026 German Aerospace Center (DLR) and others.
4// This program and the accompanying materials are made available under the
5// terms of the Eclipse Public License 2.0 which is available at
6// https://www.eclipse.org/legal/epl-2.0/
7// This Source Code may also be made available under the following Secondary
8// Licenses when the conditions for such availability set forth in the Eclipse
9// Public License 2.0 are satisfied: GNU General Public License, version 2
10// or later which is available at
11// https://www.gnu.org/licenses/old-licenses/gpl-2.0-standalone.html
12// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later
13/****************************************************************************/
18// A road/street connecting two junctions (netedit-version, adapted from GUIEdge)
19// Basically a container for an NBEdge with drawing and editing capabilities
20/****************************************************************************/
21
41#include <netedit/GNENet.h>
43#include <netedit/GNEUndoList.h>
47
48#include "GNEConnection.h"
49#include "GNECrossing.h"
50#include "GNEEdge.h"
51#include "GNEEdgeType.h"
52#include "GNELaneType.h"
53#include "GNEEdgeTemplate.h"
54#include "GNELaneTemplate.h"
55
56// ===========================================================================
57// defines
58// ===========================================================================
59
60//#define DEBUG_SMOOTH_GEOM
61//#define DEBUGCOND(obj) (true)
62#define VEHICLE_GAP 1
63#define ENDPOINT_TOLERANCE 2
64
65// ===========================================================================
66// static
67// ===========================================================================
68
71
72// ===========================================================================
73// members methods
74// ===========================================================================
75
76GNEEdge::GNEEdge(GNENet* net, NBEdge* nbe, bool wasSplit, bool loaded):
77 GNENetworkElement(net, nbe->getID(), SUMO_TAG_EDGE),
78 myNBEdge(nbe),
79 myAmResponsible(false),
80 myWasSplit(wasSplit),
81 myConnectionStatus(loaded ? FEATURE_LOADED : FEATURE_GUESSED),
82 myMoveElementEdge(new GNEMoveElementEdge(this)),
83 myUpdateGeometry(true) {
84 // set parents
85 setParents<GNEJunction*>({
86 net->getAttributeCarriers()->retrieveJunction(nbe->getFromNode()->getID()),
88 });
89 // Create lanes
90 for (int i = 0; i < myNBEdge->getNumLanes(); i++) {
91 auto lane = new GNELane(this, i);
92 lane->incRef("GNEEdge::GNEEdge");
93 addChildElement(lane);
94 }
95 // update Lane geometries
96 for (const auto& lane : getChildLanes()) {
97 lane->updateGeometry();
98 }
99 // update centering boundary without updating grid
101}
102
103
105 // Delete references to this edge in lanes
106 for (const auto& lane : getChildLanes()) {
107 lane->decRef("GNEEdge::~GNEEdge");
108 if (lane->unreferenced()) {
109 // check if remove it from Attribute Carriers
110 if (myNet->getAttributeCarriers()->getLanes().count(lane) > 0) {
112 }
113 delete lane;
114 }
115 }
116 // delete references to this edge in connections
117 for (const auto& connection : myGNEConnections) {
118 connection->decRef("GNEEdge::~GNEEdge");
119 if (connection->unreferenced()) {
120 // check if remove it from Attribute Carriers
121 if (myNet->getAttributeCarriers()->getConnections().count(connection) > 0) {
123 }
124 delete connection;
125 }
126 }
127 if (myAmResponsible) {
128 delete myNBEdge;
129 }
130}
131
132
137
138
141 return myNBEdge;
142}
143
144
145const Parameterised*
147 return myNBEdge;
148}
149
150
151bool
153 if (getFromJunction()->getNBNode()->getPosition() != getToJunction()->getNBNode()->getPosition()) {
154 return true;
155 } else {
156 return false;
157 }
158}
159
160
161std::string
163 return TLF("Parent junctions are in the same position: %, %",
164 toString(getFromJunction()->getNBNode()->getPosition().x()),
165 toString(getFromJunction()->getNBNode()->getPosition().y()));
166}
167
168
169void
171 // first check if myUpdateGeometry flag is enabled
172 if (myUpdateGeometry) {
173 // Update geometry of lanes
174 for (const auto& lane : getChildLanes()) {
175 lane->updateGeometry();
176 }
177 // Update geometry of connections
178 for (const auto& connection : myGNEConnections) {
179 connection->updateGeometry();
180 }
181 // Update geometry of additionals children vinculated to this edge
182 for (const auto& childAdditional : getChildAdditionals()) {
183 childAdditional->updateGeometry();
184 }
185 // Update geometry of additionals demand elements vinculated to this edge
186 for (const auto& childDemandElement : getChildDemandElements()) {
187 childDemandElement->updateGeometry();
188 }
189 // Update geometry of additionals generic datas vinculated to this edge
190 for (const auto& childGenericData : getChildGenericDatas()) {
191 childGenericData->updateGeometry();
192 }
193 // compute geometry of path elements elements vinculated with this edge (depending of showDemandElements)
195 for (const auto& childAdditional : getChildAdditionals()) {
196 childAdditional->computePathElement();
197 }
198 for (const auto& childDemandElement : getChildDemandElements()) {
199 childDemandElement->computePathElement();
200 }
201 for (const auto& childGenericData : getChildGenericDatas()) {
202 childGenericData->computePathElement();
203 }
204 }
205 }
206 // update vehicle geometry
208 // update stack labels
212}
213
214
217 return getChildLanes().front()->getPositionInView();
218}
219
220
221bool
223 // get modes and viewParent (for code legibility)
224 const auto& modes = myNet->getViewNet()->getEditModes();
225 const auto& viewParent = myNet->getViewParent();
226 const auto& inspectedElements = myNet->getViewNet()->getInspectedElements();
227 // continue depending of current status
228 if (inspectedElements.isInspectingSingleElement()) {
229 // check if starts in this edge
230 if (inspectedElements.getFirstAC()->getTagProperty()->vehicleEdges() &&
231 inspectedElements.getFirstAC()->hasAttribute(SUMO_ATTR_FROM) &&
232 (inspectedElements.getFirstAC()->getAttribute(SUMO_ATTR_FROM) == getID())) {
233 return true;
234 }
235 } else if (modes.isCurrentSupermodeDemand()) {
236 // get current GNEPlanCreator
237 GNEPlanCreator* planCreator = nullptr;
238 if (modes.demandEditMode == DemandEditMode::DEMAND_PERSON) {
239 planCreator = viewParent->getPersonFrame()->getPlanCreator();
240 } else if (modes.demandEditMode == DemandEditMode::DEMAND_PERSONPLAN) {
241 planCreator = viewParent->getPersonPlanFrame()->getPlanCreator();
242 } else if (modes.demandEditMode == DemandEditMode::DEMAND_CONTAINER) {
243 planCreator = viewParent->getContainerFrame()->getPlanCreator();
244 } else if (modes.demandEditMode == DemandEditMode::DEMAND_CONTAINERPLAN) {
245 planCreator = viewParent->getContainerPlanFrame()->getPlanCreator();
246 }
247 // continue depending of planCreator
248 if (planCreator) {
249 if (planCreator->getPlanParameteres().fromEdge == getID()) {
250 return true;
251 } else if ((planCreator->getPlanParameteres().consecutiveEdges.size() > 0) &&
252 (planCreator->getPlanParameteres().consecutiveEdges.front() == getID())) {
253 return true;
254 }
255 } else if (modes.demandEditMode == DemandEditMode::DEMAND_VEHICLE) {
256 const auto& selectedEdges = viewParent->getVehicleFrame()->getPathCreator()->getSelectedEdges();
257 // check if this is the first selected edge
258 if ((selectedEdges.size() > 0) && (selectedEdges.front() == this)) {
259 return true;
260 }
261 }
262 } else if (modes.isCurrentSupermodeData()) {
263 // get TAZRelDataFrame
264 const auto& edgeRelDataFrame = viewParent->getEdgeRelDataFrame();
265 if (edgeRelDataFrame->shown()) {
266 // check first Edge
267 if (edgeRelDataFrame->getPathCreator()->getSelectedEdges().empty()) {
268 return false;
269 } else {
270 return edgeRelDataFrame->getPathCreator()->getSelectedEdges().front() == this;
271 }
272 }
273 }
274 // nothing to draw
275 return false;
276}
277
278
279bool
281 // get modes and viewParent (for code legibility)
282 const auto& modes = myNet->getViewNet()->getEditModes();
283 const auto& viewParent = myNet->getViewParent();
284 const auto& inspectedElements = myNet->getViewNet()->getInspectedElements();
285 // continue depending of current status
286 if (inspectedElements.isInspectingSingleElement()) {
287 // check if starts in this edge
288 if (inspectedElements.getFirstAC()->getTagProperty()->vehicleEdges() &&
289 inspectedElements.getFirstAC()->hasAttribute(SUMO_ATTR_TO) &&
290 (inspectedElements.getFirstAC()->getAttribute(SUMO_ATTR_TO) == getID())) {
291 return true;
292 }
293 } else if (modes.isCurrentSupermodeDemand()) {
294 // get current GNEPlanCreator
295 GNEPlanCreator* planCreator = nullptr;
296 if (modes.demandEditMode == DemandEditMode::DEMAND_PERSON) {
297 planCreator = viewParent->getPersonFrame()->getPlanCreator();
298 } else if (modes.demandEditMode == DemandEditMode::DEMAND_PERSONPLAN) {
299 planCreator = viewParent->getPersonPlanFrame()->getPlanCreator();
300 } else if (modes.demandEditMode == DemandEditMode::DEMAND_CONTAINER) {
301 planCreator = viewParent->getContainerFrame()->getPlanCreator();
302 } else if (modes.demandEditMode == DemandEditMode::DEMAND_CONTAINERPLAN) {
303 planCreator = viewParent->getContainerPlanFrame()->getPlanCreator();
304 }
305 // continue depending of planCreator
306 if (planCreator) {
307 if (planCreator->getPlanParameteres().toEdge == getID()) {
308 return true;
309 } else if ((planCreator->getPlanParameteres().consecutiveEdges.size() > 1) &&
310 (planCreator->getPlanParameteres().consecutiveEdges.back() == getID())) {
311 return true;
312 }
313 } else if (modes.demandEditMode == DemandEditMode::DEMAND_VEHICLE) {
314 const auto& selectedEdges = viewParent->getVehicleFrame()->getPathCreator()->getSelectedEdges();
315 // check if this is the last selected edge
316 if ((selectedEdges.size() > 1) && (selectedEdges.back() == this)) {
317 return true;
318 }
319 }
320 } else if (modes.isCurrentSupermodeData()) {
321 // get TAZRelDataFrame
322 const auto& edgeRelDataFrame = viewParent->getEdgeRelDataFrame();
323 if (edgeRelDataFrame->shown()) {
324 // check last Edge
325 if (edgeRelDataFrame->getPathCreator()->getSelectedEdges().empty()) {
326 return false;
327 } else {
328 return edgeRelDataFrame->getPathCreator()->getSelectedEdges().back() == this;
329 }
330 }
331 }
332 // nothing to draw
333 return false;
334}
335
336
337bool
339 const auto& inspectedElements = myNet->getViewNet()->getInspectedElements();
340 // continue depending of inspected elements
341 if (inspectedElements.isInspectingSingleElement() &&
342 inspectedElements.getFirstAC()->getTagProperty()->getTag() == SUMO_TAG_TAZ) {
343 // check if one of the sourceSink child is placed in this edge
344 for (const auto& sourceSink : getChildTAZSourceSinks()) {
345 if (sourceSink->getParentAdditionals().front() == inspectedElements.getFirstAC()) {
346 return true;
347 }
348 }
349 }
350 if (myNet->getViewNet()->getPopup()) {
351 return myNet->getViewNet()->getPopup()->getGLObject() == this;
352 }
353 return false;
354}
355
356
357bool
359 // get modes and viewParent (for code legibility)
360 const auto& modes = myNet->getViewNet()->getEditModes();
361 const auto& viewParent = myNet->getViewParent();
362 const auto& viewObjectsSelector = myNet->getViewNet()->getViewObjectsSelector();
363 // check if we're selecting edges in additional mode
364 if (modes.isCurrentSupermodeNetwork() && (modes.networkEditMode == NetworkEditMode::NETWORK_ADDITIONAL)) {
365 if (viewParent->getAdditionalFrame()->getViewObjetsSelector()->isNetworkElementSelected(this)) {
366 return true;
367 } else if (viewParent->getAdditionalFrame()->getViewObjetsSelector()->getTag() == myTagProperty->getTag()) {
368 return viewObjectsSelector.getEdgeFront() == this;
369 } else {
370 return false;
371 }
372 }
373 // check if this is the edge under cursor
374 if (viewObjectsSelector.getEdgeFront() != this) {
375 return false;
376 } else {
377 // continue depending of modes
378 if (modes.isCurrentSupermodeDemand()) {
379 // get current plan selector
380 GNEPlanSelector* planSelector = nullptr;
381 if (modes.demandEditMode == DemandEditMode::DEMAND_PERSON) {
382 planSelector = viewParent->getPersonFrame()->getPlanSelector();
383 } else if (modes.demandEditMode == DemandEditMode::DEMAND_PERSONPLAN) {
384 planSelector = viewParent->getPersonPlanFrame()->getPlanSelector();
385 } else if (modes.demandEditMode == DemandEditMode::DEMAND_CONTAINER) {
386 planSelector = viewParent->getContainerFrame()->getPlanSelector();
387 } else if (modes.demandEditMode == DemandEditMode::DEMAND_CONTAINERPLAN) {
388 planSelector = viewParent->getContainerPlanFrame()->getPlanSelector();
389 }
390 // continue depending of plan selector
391 if (planSelector && planSelector->markEdges()) {
392 return (viewObjectsSelector.getAttributeCarrierFront()->getTagProperty()->getTag() == SUMO_TAG_LANE);
393 } else if (modes.demandEditMode == DemandEditMode::DEMAND_VEHICLE) {
394 // get current vehicle template
395 const auto& vehicleTemplate = viewParent->getVehicleFrame()->getVehicleTagSelector()->getCurrentTemplateAC();
396 // check if vehicle can be placed over from-to TAZs
397 if (vehicleTemplate && vehicleTemplate->getTagProperty()->vehicleEdges()) {
398 return (viewObjectsSelector.getAttributeCarrierFront()->getTagProperty()->getTag() == SUMO_TAG_LANE);
399 }
400 }
401 } else if (modes.isCurrentSupermodeData()) {
402 // get frames
403 const auto& edgeDataFrame = viewParent->getEdgeDataFrame();
404 const auto& edgeRelDataFrame = viewParent->getEdgeRelDataFrame();
405 if (edgeDataFrame->shown()) {
406 return true;
407 } else if (edgeRelDataFrame->shown()) {
408 // check edges
409 if (edgeRelDataFrame->getPathCreator()->getSelectedEdges().empty()) {
410 return true;
411 } else if (edgeRelDataFrame->getPathCreator()->getSelectedEdges().size() == 2) {
412 return false;
413 } else if (edgeRelDataFrame->getPathCreator()->getSelectedEdges().front() == this) {
414 return false;
415 } else if (edgeRelDataFrame->getPathCreator()->getSelectedEdges().back() == this) {
416 return false;
417 } else {
418 return true;
419 }
420 }
421
422 }
423 // nothing to draw
424 return false;
425 }
426}
427
428
429bool
431 // first check if we're selecting edges or lanes
433 // get edit modes
434 const auto& editModes = myNet->getViewNet()->getEditModes();
435 // check if we're in delete mode
436 if (editModes.isCurrentSupermodeNetwork() && (editModes.networkEditMode == NetworkEditMode::NETWORK_DELETE)) {
437 // check lanes
438 for (const auto& lane : getChildLanes()) {
441 return true;
442 }
443 }
444 // check edge
447 return true;
448 }
449 // nothing to draw
450 return false;
451 } else {
452 return false;
453 }
454 } else {
455 return false;
456 }
457}
458
459
460bool
462 // get edit modes
463 const auto& editModes = myNet->getViewNet()->getEditModes();
464 // check if we're in delete mode
465 if (editModes.isCurrentSupermodeNetwork() && (editModes.networkEditMode == NetworkEditMode::NETWORK_DELETE)) {
466 const auto junction = myNet->getViewNet()->getViewObjectsSelector().getJunctionFront();
468 return ((getFromJunction() == junction) || (getToJunction() == junction));
469 }
470 }
471 return false;
472}
473
474
475bool
477 // first check if we're selecting edges or lanes
479 // get edit modes
480 const auto& editModes = myNet->getViewNet()->getEditModes();
481 // check if we're in select mode
482 if (editModes.isCurrentSupermodeNetwork() && (editModes.networkEditMode == NetworkEditMode::NETWORK_SELECT)) {
483 // check lanes
484 for (const auto& lane : getChildLanes()) {
487 return true;
488 }
489 }
490 // check edge
493 return true;
494 }
495 // nothing to draw
496 return false;
497 } else {
498 return false;
499 }
500 } else {
501 return false;
502 }
503}
504
505
506bool
508 // get edit modes
509 const auto& editModes = myNet->getViewNet()->getEditModes();
510 // get move element edge
511 const auto moveElementEdge = dynamic_cast<GNEMoveElementEdge*>(myNet->getViewNet()->getMoveSingleElementValues().getMovedElement());
512 // check if we're in move mode
513 if ((!myNet->getViewNet()->isCurrentlyMovingElements() || (moveElementEdge && (moveElementEdge->getEdge() == this))) && editModes.isCurrentSupermodeNetwork() &&
514 (editModes.networkEditMode == NetworkEditMode::NETWORK_MOVE)) {
515 // check if we're editing this network element
517 if (editedNetworkElement) {
518 if (editedNetworkElement == this) {
519 return true;
520 } else {
521 // check lanes
522 for (const auto& lane : getChildLanes()) {
523 if (editedNetworkElement == lane) {
524 return true;
525 }
526 }
527 }
528 } else {
529 // check lanes
530 for (const auto& lane : getChildLanes()) {
533 return true;
534 }
535 }
536 // check edge
539 return true;
540 }
541 }
542 // nothing to draw
543 return false;
544 } else {
545 return false;
546 }
547}
548
549
550bool
552 if (myNBEdge->getGeometry().front().distanceSquaredTo2D(getFromJunction()->getNBNode()->getPosition()) > ENDPOINT_TOLERANCE) {
553 return true;
554 } else if (myNBEdge->getGeometry().back().distanceSquaredTo2D(getToJunction()->getNBNode()->getPosition()) > ENDPOINT_TOLERANCE) {
555 return true;
556 } else {
557 return false;
558 }
559}
560
561
562bool
564 // get geometry point radius
565 const double geometryPointRadius = getGeometryPointRadius();
566 if (myNBEdge->getGeometry().front().distanceSquaredTo2D(getFromJunction()->getNBNode()->getPosition()) > ENDPOINT_TOLERANCE) {
567 return (myNBEdge->getGeometry().front().distanceSquaredTo2D(pos) < (geometryPointRadius * geometryPointRadius));
568 } else {
569 return false;
570 }
571}
572
573
574bool
576 // get geometry point radius
577 const double geometryPointRadius = getGeometryPointRadius();
578 if (myNBEdge->getGeometry().back().distanceSquaredTo2D(getToJunction()->getNBNode()->getPosition()) > ENDPOINT_TOLERANCE) {
579 return (myNBEdge->getGeometry().back().distanceSquaredTo2D(pos) < (geometryPointRadius * geometryPointRadius));
580 } else {
581 return false;
582 }
583}
584
585
586bool
588 // get geometry point radius
589 const auto geometryPointRadius = getGeometryPointRadius();
590 // first check inner geometry
591 const PositionVector innenShape = myNBEdge->getInnerGeometry();
592 // iterate over geometry point
593 for (const auto& geometryPoint : innenShape) {
594 if (geometryPoint.distanceSquaredTo2D(pos) < (geometryPointRadius * geometryPointRadius)) {
595 return true;
596 }
597 }
598 // check start and end shapes
600 return true;
601 } else {
602 return false;
603 }
604}
605
606
607void
609 Position delta = junction->getNBNode()->getPosition() - origPos;
611 // geometry endpoint need not equal junction position hence we modify it with delta
612 if (junction == getFromJunction()) {
613 geom[0].add(delta);
614 } else {
615 geom[-1].add(delta);
616 }
617 setGeometry(geom, false);
618}
619
620
621double
623 return s.addSize.getExaggeration(s, this);
624}
625
626
631
632
633void
634GNEEdge::updateCenteringBoundary(const bool updateGrid) {
635 // Remove object from net
636 if (updateGrid) {
638 }
639 // first add edge boundary
641 // add lane boundaries
642 for (const auto& lane : getChildLanes()) {
643 const auto laneBoundary = lane->getCenteringBoundary();
644 if (laneBoundary.isInitialised()) {
645 myEdgeBoundary.add(laneBoundary);
646 // add additional and demand boundaries
647 for (const auto& additional : lane->getChildAdditionals()) {
648 const auto additionalBoundary = additional->getCenteringBoundary();
649 if (additionalBoundary.isInitialised()) {
650 myEdgeBoundary.add(additional->getCenteringBoundary());
651 }
652 }
653 }
654 }
655 // add additional and demand boundaries
656 for (const auto& additional : getChildAdditionals()) {
657 const auto additionalBoundary = additional->getCenteringBoundary();
658 if (additionalBoundary.isInitialised()) {
659 myEdgeBoundary.add(additionalBoundary);
660 }
661 }
662 // add junction positions
665 // grow boundary
667 // add object into net
668 if (updateGrid) {
670 }
671}
672
673
674const std::string
676 return myNBEdge->getStreetName();
677}
678
679
682 // if we call this function, that's mean that we're clicked over a edge geometry point, then
683 // open the popup dialog of the lane[0] (back)
684 return getChildLanes().back()->getPopUpMenu(app, parent);
685}
686
687
688std::vector<GNEEdge*>
692
693
694void
696 // check drawing boundary selection and size boundary
698 // draw boundary
700 // get detail level from the first lane
701 const auto d = getChildLanes().front()->getDrawingConstants()->getDetail();
702 // calculate layer
703 double layer = GLO_EDGE;
704 if (myDrawInFront) {
705 layer = GLO_FRONTELEMENT;
706 } else if (getChildLanes().front()->getLaneShape().length2D() <= (s.neteditSizeSettings.junctionBubbleRadius * 2)) {
707 layer = GLO_JUNCTION + 1.8;
708 }
709 // check if draw details
711 // draw geometry points
712 drawEdgeGeometryPoints(s, d, layer);
713 // draw edge shape (a red line only visible if lane shape is strange)
714 drawEdgeShape(s, d, layer);
715 // draw edge stopOffset
716 drawLaneStopOffset(s, d, layer);
717 // draw edge name
718 drawEdgeName(s);
719 // draw lock icon
721 // draw dotted contour
723 }
724 // calculate edge contour (always before children)
725 calculateEdgeContour(s, d, layer);
726 // draw lanes
727 for (const auto& lane : getChildLanes()) {
728 lane->drawGL(s);
729 }
730 // draw junctions
732 getToJunction()->drawGL(s);
733 // draw childrens
734 drawChildrens(s);
735 }
736}
737
738
739void
741 // Check if edge can be deleted
743 myNet->deleteEdge(this, myNet->getUndoList(), false);
744 }
745}
746
747
748void
752
753
754NBEdge*
756 return myNBEdge;
757}
758
759
762 // get geometry point radius
763 const double geometryPointRadius = getGeometryPointRadius();
764 const PositionVector& geom = myNBEdge->getGeometry();
765 int index = geom.indexOfClosest(clickPos, true);
766 if (geom[index].distanceSquaredTo2D(clickPos) < (geometryPointRadius * geometryPointRadius)) {
767 // split at existing geometry point
768 return myNet->getViewNet()->snapToActiveGrid(geom[index]);
769 } else {
770 // split straight between the next two points
772 }
773}
774
775
776void
778 // get geometry point radius
779 const double geometryPointRadius = getGeometryPointRadius();
780 if ((myNBEdge->getGeometry().front().distanceSquaredTo2D(getFromJunction()->getNBNode()->getPosition()) > ENDPOINT_TOLERANCE) &&
781 (myNBEdge->getGeometry().front().distanceSquaredTo2D(pos) < (geometryPointRadius * geometryPointRadius))) {
782 undoList->begin(this, "remove endpoint");
783 setAttribute(GNE_ATTR_SHAPE_START, "", undoList);
784 undoList->end();
785 } else if ((myNBEdge->getGeometry().back().distanceSquaredTo2D(getToJunction()->getNBNode()->getPosition()) > ENDPOINT_TOLERANCE) &&
786 (myNBEdge->getGeometry().back().distanceSquaredTo2D(pos) < (geometryPointRadius * geometryPointRadius))) {
787 undoList->begin(this, "remove endpoint");
788 setAttribute(GNE_ATTR_SHAPE_END, "", undoList);
789 undoList->end();
790 } else {
791 // we need to create new Start/End position over Edge shape, not over clicked position
793 if (offset != GeomHelper::INVALID_OFFSET) {
795 // calculate position over edge shape relative to clicked position
796 Position newPos = geom.positionAtOffset2D(offset);
797 // snap new position to grid
798 newPos = myNet->getViewNet()->snapToActiveGrid(newPos);
799 undoList->begin(this, "set endpoint");
800 const int index = geom.indexOfClosest(pos, true);
801 const Position destPos = getToJunction()->getNBNode()->getPosition();
802 const Position sourcePos = getFromJunction()->getNBNode()->getPosition();
803 if (pos.distanceTo2D(destPos) < pos.distanceTo2D(sourcePos)) {
804 // check if snap to existing geometrypoint
805 if (geom[index].distanceSquaredTo2D(pos) < (geometryPointRadius * geometryPointRadius)) {
806 newPos = geom[index];
807 // remove existent geometry point to avoid double points
808 myMoveElementEdge->removeGeometryPoint(newPos, undoList);
809 }
810 setAttribute(GNE_ATTR_SHAPE_END, toString(newPos), undoList);
812 } else {
813 // check if snap to existing geometry point
814 if (geom[index].distanceSquaredTo2D(pos) < (geometryPointRadius * geometryPointRadius)) {
815 newPos = geom[index];
816 // remove existent geometry point to avoid double points
817 myMoveElementEdge->removeGeometryPoint(newPos, undoList);
818 }
819 setAttribute(GNE_ATTR_SHAPE_START, toString(newPos), undoList);
821 }
822 undoList->end();
823 }
824 }
825}
826
827
828void
831 Position sourcePos = getFromJunction()->getNBNode()->getPosition();
832 if (pos.distanceTo2D(destPos) < pos.distanceTo2D(sourcePos)) {
833 setAttribute(GNE_ATTR_SHAPE_END, toString(destPos), undoList);
835 } else {
836 setAttribute(GNE_ATTR_SHAPE_START, toString(sourcePos), undoList);
838 }
839}
840
841
842void
844 // reset shape start
845 setAttribute(GNE_ATTR_SHAPE_END, "", undoList);
847 // reset shape end
848 setAttribute(GNE_ATTR_SHAPE_START, "", undoList);
850}
851
852void
854 // set new geometry
855 const bool lefthand = OptionsCont::getOptions().getBool("lefthand");
856 if (lefthand) {
857 geom.mirrorX();
858 myNBEdge->mirrorX();
859 }
860 myNBEdge->setGeometry(geom, inner);
861 if (lefthand) {
862 myNBEdge->mirrorX();
863 }
864 // update geometry
866 // invalidate junction source shape
868 // iterate over first parent junction edges and update geometry
869 for (const auto& edge : getFromJunction()->getGNEIncomingEdges()) {
870 edge->updateGeometry();
871 }
872 for (const auto& edge : getFromJunction()->getGNEOutgoingEdges()) {
873 edge->updateGeometry();
874 }
875 // invalidate junction destination shape
877 // iterate over second parent junction edges and update geometry
878 for (const auto& edge : getToJunction()->getGNEIncomingEdges()) {
879 edge->updateGeometry();
880 }
881 for (const auto& edge : getToJunction()->getGNEOutgoingEdges()) {
882 edge->updateGeometry();
883 }
884}
885
886
887const Position
889 PositionVector laneShape = getChildLanes().front()->getLaneShape();
890 laneShape.move2side(getChildLanes().front()->getParentEdge()->getNBEdge()->getLaneWidth(getChildLanes().front()->getIndex()) / 2);
891 return laneShape.front();
892}
893
894
895const Position
897 PositionVector laneShape = getChildLanes().back()->getLaneShape();
898 laneShape.move2side(-1 * getChildLanes().back()->getParentEdge()->getNBEdge()->getLaneWidth(getChildLanes().back()->getIndex()) / 2);
899 return laneShape.front();
900}
901
902
903const Position
905 PositionVector laneShape = getChildLanes().front()->getLaneShape();
906 laneShape.move2side(getChildLanes().front()->getParentEdge()->getNBEdge()->getLaneWidth(getChildLanes().front()->getIndex()) / 2);
907 return laneShape.back();
908}
909
910
911const Position
913 PositionVector laneShape = getChildLanes().back()->getLaneShape();
914 laneShape.move2side(-1 * getChildLanes().back()->getParentEdge()->getNBEdge()->getLaneWidth(getChildLanes().back()->getIndex()) / 2);
915 return laneShape.back();
916}
917
918void
919GNEEdge::remakeGNEConnections(bool junctionsReady) {
920 // create new and removed unused GNEConnections
921 const std::vector<NBEdge::Connection>& connections = myNBEdge->getConnections();
922 // create a vector to keep retrieved and created connections
923 std::vector<GNEConnection*> retrievedConnections;
924 // iterate over NBEdge::Connections of GNEEdge
925 for (const auto& connection : connections) {
926 // retrieve existent GNEConnection, or create it
927 GNEConnection* retrievedGNEConnection = retrieveGNEConnection(connection.fromLane, connection.toEdge, connection.toLane);
928 if (junctionsReady) {
929 retrievedGNEConnection->updateLinkState();
930 }
931 retrievedConnections.push_back(retrievedGNEConnection);
932 // check if previously this GNEConnections exists, and if true, remove it from myGNEConnections
933 std::vector<GNEConnection*>::iterator retrievedExists = std::find(myGNEConnections.begin(), myGNEConnections.end(), retrievedGNEConnection);
934 if (retrievedExists != myGNEConnections.end()) {
935 myGNEConnections.erase(retrievedExists);
936 } else {
937 // include reference to created GNEConnection
938 retrievedGNEConnection->incRef("GNEEdge::remakeGNEConnections");
939 }
940 // mark it as deprecated
941 retrievedGNEConnection->markConnectionGeometryDeprecated();
942 }
943 // delete non retrieved GNEConnections
944 for (const auto& connection : myGNEConnections) {
945 // decrease reference
946 connection->decRef();
947 // remove it from network
948 myNet->removeGLObjectFromGrid(connection);
949 // and from AttributeCarriers
950 if (myNet->getAttributeCarriers()->getConnections().count(connection) > 0) {
952 }
953 // delete GNEConnection if is unreferenced
954 if (connection->unreferenced()) {
955 delete connection;
956 }
957 }
958 // copy retrieved (existent and created) GNECrossings to myGNEConnections
959 myGNEConnections = retrievedConnections;
960}
961
962
963void
965 // Drop all existents connections that aren't referenced anymore
966 for (const auto& connection : myGNEConnections) {
967 // check if connection is selected
968 if (connection->isAttributeCarrierSelected()) {
969 connection->unselectAttributeCarrier();
970 }
971 // Dec reference of connection
972 connection->decRef("GNEEdge::clearGNEConnections");
973 // remove it from network
974 myNet->removeGLObjectFromGrid(connection);
975 // and from AttributeCarriers
976 if (myNet->getAttributeCarriers()->getConnections().count(connection) > 0) {
978 }
979 // Delete GNEConnectionToErase if is unreferenced
980 if (connection->unreferenced()) {
981 delete connection;
982 }
983 }
984 myGNEConnections.clear();
985}
986
987
988int
990 std::vector<GNEAdditional*> routeProbes;
991 for (const auto& additional : getChildAdditionals()) {
992 if (additional->getTagProperty()->getTag() == routeProbe->getTagProperty()->getTag()) {
993 routeProbes.push_back(additional);
994 }
995 }
996 // return index of routeProbe in routeProbes vector
997 auto it = std::find(routeProbes.begin(), routeProbes.end(), routeProbe);
998 if (it == routeProbes.end()) {
999 return -1;
1000 } else {
1001 return (int)(it - routeProbes.begin());
1002 }
1003}
1004
1005
1006std::vector<GNECrossing*>
1008 std::vector<GNECrossing*> crossings;
1009 for (auto i : getFromJunction()->getGNECrossings()) {
1010 if (i->checkEdgeBelong(this)) {
1011 crossings.push_back(i);
1012 }
1013 }
1014 for (auto i : getToJunction()->getGNECrossings()) {
1015 if (i->checkEdgeBelong(this)) {
1016 crossings.push_back(i);
1017 }
1018 }
1019 return crossings;
1020}
1021
1022
1023void
1024GNEEdge::copyTemplate(const GNEEdgeTemplate* edgeTemplate, GNEUndoList* undoList) {
1025 // copy edge-specific attributes
1026 for (const auto& attProperty : myTagProperty->getAttributeProperties()) {
1027 if (attProperty->isCopyable() && isValid(attProperty->getAttr(), edgeTemplate->getAttribute(attProperty->getAttr()))) {
1028 setAttribute(attProperty->getAttr(), edgeTemplate->getAttribute(attProperty->getAttr()), undoList);
1029 }
1030 }
1031 // also copy parameters
1033 // copy lane attributes as well
1034 for (int i = 0; i < (int)getChildLanes().size(); i++) {
1035 for (const auto& attProperty : edgeTemplate->getLaneTemplates().at(i)->getTagProperty()->getAttributeProperties()) {
1036 if (attProperty->isCopyable() && getChildLanes()[i]->isValid(attProperty->getAttr(), edgeTemplate->getLaneTemplates().at(i)->getAttribute(attProperty->getAttr()))) {
1037 getChildLanes()[i]->setAttribute(attProperty->getAttr(), edgeTemplate->getLaneTemplates().at(i)->getAttribute(attProperty->getAttr()), undoList);
1038 }
1039 }
1040 // also copy parameters
1041 getChildLanes()[i]->setAttribute(GNE_ATTR_PARAMETERS, edgeTemplate->getLaneTemplates().at(i)->getAttribute(GNE_ATTR_PARAMETERS), undoList);
1042 }
1043}
1044
1045
1046void
1047GNEEdge::copyEdgeType(const GNEEdgeType* edgeType, GNEUndoList* undoList) {
1048 const auto tagPropertiesDatabase = myNet->getTagPropertiesDatabase();
1049 // get tag properties
1050 const auto edgeProperties = tagPropertiesDatabase->getTagProperty(SUMO_TAG_EDGE, true);
1051 const auto laneProperties = tagPropertiesDatabase->getTagProperty(SUMO_TAG_LANE, true);
1052 const auto edgeTypeProperties = tagPropertiesDatabase->getTagProperty(SUMO_TAG_TYPE, true);
1053 const auto laneTypeProperties = tagPropertiesDatabase->getTagProperty(SUMO_TAG_LANETYPE, true);
1054 // set type (only for info)
1056 // copy attributes
1057 for (const auto& attrProperty : edgeTypeProperties->getAttributeProperties()) {
1058 if (attrProperty->isCopyable() && edgeProperties->hasAttribute(attrProperty->getAttr())) {
1059 setAttribute(attrProperty->getAttr(), edgeType->getAttribute(attrProperty->getAttr()), undoList);
1060 }
1061 }
1063 // copy lane attributes as well
1064 for (int i = 0; i < (int)getChildLanes().size(); i++) {
1065 for (const auto& attrProperty : laneTypeProperties->getAttributeProperties()) {
1066 if (attrProperty->isCopyable() && laneProperties->hasAttribute(attrProperty->getAttr()) &&
1067 (edgeType->getLaneTypes().at(i)->getAttribute(attrProperty->getAttr()) != laneTypeProperties->getAttributeProperties(attrProperty->getAttr())->getDefaultStringValue())) {
1068 getChildLanes()[i]->setAttribute(attrProperty->getAttr(), edgeType->getLaneTypes().at(i)->getAttribute(attrProperty->getAttr()), undoList);
1069 }
1070 }
1071 if (edgeType->getLaneTypes().at(i)->getAttribute(GNE_ATTR_PARAMETERS).size() > 0) {
1072 getChildLanes()[i]->setAttribute(GNE_ATTR_PARAMETERS, edgeType->getLaneTypes().at(i)->getAttribute(GNE_ATTR_PARAMETERS), undoList);
1073 }
1074 }
1075}
1076
1077
1078std::set<GUIGlID>
1080 std::set<GUIGlID> result;
1081 for (const auto glID : getChildLanes()) {
1082 result.insert(glID->getGlID());
1083 }
1084 return result;
1085}
1086
1087
1088const std::vector<GNEConnection*>&
1092
1093
1094bool
1096 return myWasSplit;
1097}
1098
1099
1100std::string
1102 switch (key) {
1103 case SUMO_ATTR_ID:
1104 return getMicrosimID();
1105 case SUMO_ATTR_FROM:
1107 return getFromJunction()->getID();
1108 case SUMO_ATTR_TO:
1110 return getToJunction()->getID();
1111 case SUMO_ATTR_NUMLANES:
1112 return toString(myNBEdge->getNumLanes());
1113 case SUMO_ATTR_PRIORITY:
1114 return toString(myNBEdge->getPriority());
1115 case SUMO_ATTR_LENGTH:
1116 return toString(myNBEdge->getFinalLength());
1117 case SUMO_ATTR_TYPE:
1118 return myNBEdge->getTypeID();
1120 return myNBEdge->getRoutingType();
1121 case SUMO_ATTR_SHAPE:
1125 case SUMO_ATTR_NAME:
1126 return myNBEdge->getStreetName();
1127 case SUMO_ATTR_ALLOW:
1128 return (getVehicleClassNames(myNBEdge->getPermissions()) + (myNBEdge->hasLaneSpecificPermissions() ? " (combined!)" : ""));
1129 case SUMO_ATTR_DISALLOW: {
1131 }
1132 case SUMO_ATTR_SPEED:
1134 return "lane specific";
1135 } else {
1136 return toString(myNBEdge->getSpeed());
1137 }
1138 case SUMO_ATTR_FRICTION:
1140 return "lane specific";
1141 } else {
1142 return toString(myNBEdge->getFriction());
1143 }
1144 case SUMO_ATTR_WIDTH:
1146 return "lane specific";
1148 return "default";
1149 } else {
1150 return toString(myNBEdge->getLaneWidth());
1151 }
1154 return "lane specific";
1155 } else {
1156 return toString(myNBEdge->getEndOffset());
1157 }
1158 case SUMO_ATTR_DISTANCE:
1159 return toString(myNBEdge->getDistance());
1161 return myConnectionStatus;
1163 if (getParentJunctions().empty()) {
1164 return "";
1165 } else if (myNBEdge->getGeometry().front().distanceSquaredTo2D(getFromJunction()->getNBNode()->getPosition()) <= ENDPOINT_TOLERANCE) {
1166 return "";
1167 } else {
1168 return toString(myNBEdge->getGeometry().front());
1169 }
1170 case GNE_ATTR_SHAPE_END:
1171 if (getParentJunctions().empty()) {
1172 return "";
1173 } else if (myNBEdge->getGeometry().back().distanceSquaredTo2D(getToJunction()->getNBNode()->getPosition()) <= ENDPOINT_TOLERANCE) {
1174 return "";
1175 } else {
1176 return toString(myNBEdge->getGeometry().back());
1177 }
1178 case GNE_ATTR_BIDIR:
1179 return toString(myNBEdge->getBidiEdge() != nullptr);
1185 } else {
1186 return "";
1187 }
1190 default:
1191 return getCommonAttribute(key);
1192 }
1193}
1194
1195
1196double
1200
1201
1206
1207
1210 switch (key) {
1211 case SUMO_ATTR_SHAPE:
1212 return myNBEdge->getInnerGeometry();
1213 default:
1215 }
1216}
1217
1218
1219std::string
1221 std::string result = getAttribute(key);
1222 if ((key == SUMO_ATTR_ALLOW || key == SUMO_ATTR_DISALLOW) && result.find("all") != std::string::npos) {
1223 result += " " + getVehicleClassNames(SVCAll, true);
1224 }
1225 return result;
1226}
1227
1228
1229void
1230GNEEdge::setAttribute(SumoXMLAttr key, const std::string& value, GNEUndoList* undoList) {
1231 // get template editor
1233 // check if we have to update template
1234 const bool updateTemplate = templateEditor->getEdgeTemplate() ? (templateEditor->getEdgeTemplate()->getID() == getID()) : false;
1235 switch (key) {
1236 case SUMO_ATTR_WIDTH:
1238 case SUMO_ATTR_SPEED:
1239 case SUMO_ATTR_FRICTION:
1240 case SUMO_ATTR_ALLOW:
1241 case SUMO_ATTR_DISALLOW: {
1242 undoList->begin(this, "change " + getTagStr() + " attribute");
1243 const std::string origValue = getChildLanes().at(0)->getAttribute(key); // will have intermediate value of "lane specific"
1244 // lane specific attributes need to be changed via lanes to allow undo
1245 for (auto it : getChildLanes()) {
1246 it->setAttribute(key, value, undoList);
1247 }
1248 // ensure that the edge value is also changed. Actually this sets the lane attributes again but it does not matter
1249 GNEChange_Attribute::changeAttribute(this, key, value, origValue, undoList);
1250 undoList->end();
1251 break;
1252 }
1253 case SUMO_ATTR_FROM: {
1254 if (value != getAttribute(key)) {
1255 undoList->begin(this, "change " + getTagStr() + " attribute");
1256 // Remove edge from crossings of junction source
1258 // continue changing from junction
1259 GNEJunction* originalFirstParentJunction = getFromJunction();
1260 getFromJunction()->setLogicValid(false, undoList);
1261 GNEChange_Attribute::changeAttribute(this, key, value, undoList);
1262 getFromJunction()->setLogicValid(false, undoList);
1263 myNet->getAttributeCarriers()->retrieveJunction(value)->setLogicValid(false, undoList);
1264 setAttribute(GNE_ATTR_SHAPE_START, toString(getFromJunction()->getNBNode()->getPosition()), undoList);
1266 undoList->end();
1267 // update geometries of all implicated junctions
1268 originalFirstParentJunction->updateGeometry();
1271 }
1272 break;
1273 }
1274 case SUMO_ATTR_TO: {
1275 if (value != getAttribute(key)) {
1276 undoList->begin(this, "change " + getTagStr() + " attribute");
1277 // Remove edge from crossings of junction destination
1279 // continue changing destination junction
1280 GNEJunction* originalSecondParentJunction = getToJunction();
1281 getToJunction()->setLogicValid(false, undoList);
1282 GNEChange_Attribute::changeAttribute(this, key, value, undoList);
1283 getToJunction()->setLogicValid(false, undoList);
1284 myNet->getAttributeCarriers()->retrieveJunction(value)->setLogicValid(false, undoList);
1285 setAttribute(GNE_ATTR_SHAPE_END, toString(getToJunction()->getNBNode()->getPosition()), undoList);
1287 undoList->end();
1288 // update geometries of all implicated junctions
1289 originalSecondParentJunction->updateGeometry();
1292 }
1293 break;
1294 }
1295 case SUMO_ATTR_ID:
1296 case SUMO_ATTR_PRIORITY:
1297 case SUMO_ATTR_LENGTH:
1298 case SUMO_ATTR_TYPE:
1301 case SUMO_ATTR_DISTANCE:
1304 GNEChange_Attribute::changeAttribute(this, key, value, undoList);
1305 break;
1307 // special case for stop offset, because affects to stopOffsetExceptions (#15297)
1308 if (canParse<double>(value) && (parse<double>(value) == 0)) {
1310 }
1311 GNEChange_Attribute::changeAttribute(this, key, value, undoList);
1312 break;
1314 case GNE_ATTR_SHAPE_END: {
1315 // due to ENDPOINT_TOLERANCE, force change
1316 GNEChange_Attribute::changeAttribute(this, key, value, undoList, true);
1317 break;
1318 }
1319 case SUMO_ATTR_NAME:
1320 // user cares about street names. Make sure they appear in the output
1322 OptionsCont::getOptions().set("output.street-names", "true");
1323 GNEChange_Attribute::changeAttribute(this, key, value, undoList);
1324 break;
1325 case SUMO_ATTR_NUMLANES:
1326 if (value != getAttribute(key)) {
1327 // set num lanes
1328 setNumLanes(parse<int>(value), undoList);
1329 }
1330 break;
1331 case GNE_ATTR_BIDIR:
1332 undoList->begin(this, "change " + getTagStr() + " attribute");
1333 GNEChange_Attribute::changeAttribute(this, key, value, undoList);
1334 if (myNBEdge->getTurnDestination(true) != nullptr) {
1336 GNEChange_Attribute::changeAttribute(bidi, key, value, undoList);
1337 if (myNBEdge->getGeometry() != bidi->getNBEdge()->getGeometry().reverse()
1338 && myNBEdge->getGeometry().size() == 2
1339 && bidi->getNBEdge()->getGeometry().size() == 2
1340 && myNBEdge->getBidiEdge() == nullptr) {
1341 // NBEdge::avoidOverlap was already active so we need to reset the
1342 // geometry to its default
1343 resetBothEndpoint(undoList);
1344 bidi->resetBothEndpoint(undoList);
1345 }
1346 }
1347 undoList->end();
1348 break;
1349 case SUMO_ATTR_SHAPE:
1350 // @note: assumes value of inner geometry!
1351 // actually the geometry is already updated (incrementally
1352 // during mouse movement). We set the restore point to the end
1353 // of the last change-set
1354 GNEChange_Attribute::changeAttribute(this, key, value, undoList);
1355 break;
1356 default:
1357 setCommonAttribute(key, value, undoList);
1358 break;
1359 }
1360 // update template
1361 if (updateTemplate) {
1362 templateEditor->setEdgeTemplate(this);
1363 }
1364}
1365
1366
1367bool
1368GNEEdge::isValid(SumoXMLAttr key, const std::string& value) {
1369 switch (key) {
1370 case SUMO_ATTR_ID:
1371 return SUMOXMLDefinitions::isValidNetID(value) && (myNet->getAttributeCarriers()->retrieveEdge(value, false) == nullptr);
1372 case SUMO_ATTR_FROM: {
1373 // check that is a valid ID and is different of ID of junction destination
1374 if (value == getFromJunction()->getID()) {
1375 return true;
1376 } else if (SUMOXMLDefinitions::isValidNetID(value) && (value != getToJunction()->getID())) {
1377 return (myNet->getAttributeCarriers()->retrieveJunction(value, false) != nullptr);
1378 } else {
1379 return false;
1380 }
1381 }
1382 case SUMO_ATTR_TO: {
1383 // check that is a valid ID and is different of ID of junction Source
1384 if (value == getToJunction()->getID()) {
1385 return true;
1386 } else if (SUMOXMLDefinitions::isValidNetID(value) && (value != getFromJunction()->getID())) {
1387 return (myNet->getAttributeCarriers()->retrieveJunction(value, false) != nullptr);
1388 } else {
1389 return false;
1390 }
1391 }
1392 case SUMO_ATTR_SPEED:
1393 return canParse<double>(value) && (parse<double>(value) > 0);
1394 case SUMO_ATTR_FRICTION:
1395 return canParse<double>(value) && (parse<double>(value) > 0);
1396 case SUMO_ATTR_NUMLANES:
1397 return canParse<int>(value) && (parse<double>(value) > 0);
1398 case SUMO_ATTR_PRIORITY:
1399 return canParse<int>(value);
1400 case SUMO_ATTR_LENGTH:
1401 if (value.empty()) {
1402 return true;
1403 } else {
1404 return canParse<double>(value) && ((parse<double>(value) > 0) || (parse<double>(value) == NBEdge::UNSPECIFIED_LOADED_LENGTH));
1405 }
1406 case SUMO_ATTR_ALLOW:
1407 case SUMO_ATTR_DISALLOW:
1408 return canParseVehicleClasses(value);
1409 case SUMO_ATTR_TYPE:
1411 return true;
1412 case SUMO_ATTR_SHAPE:
1413 // empty shapes are allowed
1414 return canParse<PositionVector>(value);
1417 case SUMO_ATTR_NAME:
1418 return true;
1419 case SUMO_ATTR_WIDTH:
1420 if (value.empty() || (value == "default")) {
1421 return true;
1422 } else {
1423 return canParse<double>(value) && ((parse<double>(value) >= -1) || (parse<double>(value) == NBEdge::UNSPECIFIED_WIDTH));
1424 }
1426 return canParse<double>(value) && parse<double>(value) >= 0 && parse<double>(value) < myNBEdge->getLoadedLength();
1427 case SUMO_ATTR_DISTANCE:
1428 if (value.empty()) {
1429 return true;
1430 } else {
1431 return canParse<double>(value);
1432 }
1433 case GNE_ATTR_SHAPE_START: {
1434 if (value.empty()) {
1435 return true;
1436 } else if (canParse<Position>(value)) {
1437 Position shapeStart = parse<Position>(value);
1438 return (shapeStart != myNBEdge->getGeometry()[-1]);
1439 } else {
1440 return false;
1441 }
1442 }
1443 case GNE_ATTR_SHAPE_END: {
1444 if (value.empty()) {
1445 return true;
1446 } else if (canParse<Position>(value)) {
1447 Position shapeEnd = parse<Position>(value);
1448 return (shapeEnd != myNBEdge->getGeometry()[0]);
1449 } else {
1450 return false;
1451 }
1452 }
1453 case GNE_ATTR_BIDIR:
1454 return canParse<bool>(value) && (!parse<bool>(value) || myNBEdge->isBidiEdge(true));
1456 if (value.empty()) {
1457 return true;
1458 } else {
1459 return canParse<double>(value) && (parse<double>(value) >= 0);
1460 }
1462 return canParseVehicleClasses(value);
1463 default:
1464 return isCommonAttributeValid(key, value);
1465 }
1466}
1467
1468
1469bool
1471 switch (key) {
1472 case GNE_ATTR_BIDIR:
1473 return myNBEdge->isBidiEdge(true);
1475 return myNBEdge->myEdgeStopOffset.getOffset() > 0;
1477 return false;
1478 default:
1479 return true;
1480 }
1481}
1482
1483
1484bool
1486 switch (key) {
1487 case SUMO_ATTR_LENGTH:
1488 return !myNBEdge->hasLoadedLength();
1489 case SUMO_ATTR_WIDTH:
1491 return false;
1492 } else {
1494 }
1495 default:
1496 return false;
1497 }
1498}
1499
1500
1501void
1503 myAmResponsible = newVal;
1504}
1505
1506
1507GNELane*
1509 // iterate over all NBEdge lanes
1510 for (int i = 0; i < (int)myNBEdge->getLanes().size(); i++) {
1511 // if given VClass is in permissions, return lane
1512 if (myNBEdge->getLanes().at(i).permissions & vClass) {
1513 // return GNELane
1514 return getChildLanes().at(i);
1515 }
1516 }
1517 // return first lane
1518 return getChildLanes().front();
1519}
1520
1521
1522GNELane*
1524 // iterate over all NBEdge lanes
1525 for (int i = 0; i < (int)myNBEdge->getLanes().size(); i++) {
1526 // if given VClass isn't in permissions, return lane
1527 if (~(myNBEdge->getLanes().at(i).permissions) & vClass) {
1528 // return GNELane
1529 return getChildLanes().at(i);
1530 }
1531 }
1532 // return first lane
1533 return getChildLanes().front();
1534}
1535
1536
1537void
1539 // get lane vehicles map
1540 const std::map<const GNELane*, std::vector<GNEDemandElement*> > laneVehiclesMap = getVehiclesOverEdgeMap();
1541 // iterate over every lane
1542 for (const auto& laneVehicle : laneVehiclesMap) {
1543 // obtain total length
1544 double totalLength = 0;
1545 for (const auto& vehicle : laneVehicle.second) {
1546 totalLength += vehicle->getAttributeDouble(SUMO_ATTR_LENGTH) + VEHICLE_GAP;
1547 }
1548 // calculate multiplier for vehicle positions
1549 double multiplier = 1;
1550 const double laneShapeLength = laneVehicle.first->getLaneShape().length();
1551 if (laneShapeLength == 0) {
1552 multiplier = 0;
1553 } else if (totalLength > laneShapeLength) {
1554 multiplier = (laneShapeLength / totalLength);
1555 }
1556 // declare current length
1557 double length = 0;
1558 // iterate over vehicles to calculate position and rotations
1559 for (const auto& vehicle : laneVehicle.second) {
1560 vehicle->updateDemandElementSpreadGeometry(laneVehicle.first, length * multiplier);
1561 // update length
1562 length += vehicle->getAttributeDouble(SUMO_ATTR_LENGTH) + VEHICLE_GAP;
1563 }
1564 }
1565}
1566
1567
1568void
1570 // get lane vehicles map
1571 const std::map<const GNELane*, std::vector<GNEDemandElement*> > laneVehiclesMap = getVehiclesOverEdgeMap();
1572 // iterate over laneVehiclesMap and obtain a vector with
1573 for (const auto& vehicleMap : laneVehiclesMap) {
1574 // declare map for sort vehicles using their departpos+length position (StackPosition)
1575 std::vector<std::pair<GNEEdge::StackPosition, GNEDemandElement*> > departPosVehicles;
1576 // declare vector of stack demand elements
1577 std::vector<GNEEdge::StackDemandElements> stackedVehicles;
1578 // iterate over vehicles
1579 for (const auto& vehicle : vehicleMap.second) {
1580 // get vehicle's depart pos and length
1581 const double departPos = vehicle->getAttributeDouble(SUMO_ATTR_DEPARTPOS);
1582 const double length = vehicle->getAttributeDouble(SUMO_ATTR_LENGTH);
1583 double posOverLane = vehicle->getAttributeDouble(SUMO_ATTR_DEPARTPOS);
1584 // check if we have to adapt posOverLane
1585 if (posOverLane < 0) {
1586 posOverLane += vehicleMap.first->getLaneShape().length();
1587 }
1588 // make a stack position using departPos and length
1589 departPosVehicles.push_back(std::make_pair(StackPosition(departPos, length), vehicle));
1590 // update depart element geometry
1591 vehicle->updateDemandElementGeometry(vehicleMap.first, posOverLane);
1592 // reset vehicle stack label
1593 vehicle->updateDemandElementStackLabel(0);
1594 }
1595
1596 // sort departPosVehicles
1597 std::sort(departPosVehicles.begin(), departPosVehicles.end());
1598 // iterate over departPosVehicles
1599 for (const auto& departPosVehicle : departPosVehicles) {
1600 // obtain stack position and vehicle
1601 const GNEEdge::StackPosition& vehicleStackPosition = departPosVehicle.first;
1602 GNEDemandElement* vehicle = departPosVehicle.second;
1603 // if stackedVehicles is empty, add a new StackDemandElements
1604 if (stackedVehicles.empty()) {
1605 stackedVehicles.push_back(GNEEdge::StackDemandElements(vehicleStackPosition, vehicle));
1606 } else if (areStackPositionOverlapped(vehicleStackPosition, stackedVehicles.back().getStackPosition())) {
1607 // add new vehicle to last inserted stackDemandElements
1608 stackedVehicles[stackedVehicles.size() - 1].addDemandElements(vehicle);
1609 } else {
1610 // No overlapping, then add a new StackDemandElements
1611 stackedVehicles.push_back(GNEEdge::StackDemandElements(vehicleStackPosition, vehicle));
1612 }
1613 }
1614 // iterate over stackedVehicles
1615 for (const auto& vehicle : stackedVehicles) {
1616 // only update vehicles with one or more stack
1617 if (vehicle.getDemandElements().size() > 1) {
1618 // set stack labels
1619 vehicle.getDemandElements().front()->updateDemandElementStackLabel((int)vehicle.getDemandElements().size());
1620 }
1621 }
1622 }
1623}
1624
1625
1626void
1628 // get lane persons map
1629 const std::map<const GNELane*, std::vector<GNEDemandElement*> > lanePersonsMap = getPersonsOverEdgeMap();
1630 // iterate over lanePersonsMap and obtain a vector with
1631 for (const auto& personMap : lanePersonsMap) {
1632 // declare map for sort persons using their departpos+length position (StackPosition)
1633 std::vector<std::pair<GNEEdge::StackPosition, GNEDemandElement*> > departPosPersons;
1634 // declare vector of stack demand elements
1635 std::vector<GNEEdge::StackDemandElements> stackedPersons;
1636 // iterate over persons
1637 for (const auto& person : personMap.second) {
1638 // get person's depart pos and length
1639 const double departPos = person->getAttributeDouble(SUMO_ATTR_DEPARTPOS);
1640 // make a stack position using departPos and length
1641 departPosPersons.push_back(std::make_pair(StackPosition(departPos, 1.8), person));
1642 // update depart element geometry
1643 person->updateDemandElementGeometry(personMap.first, departPos);
1644 // reset person stack label
1645 person->updateDemandElementStackLabel(0);
1646 }
1647
1648 // sort departPosPersons
1649 std::sort(departPosPersons.begin(), departPosPersons.end());
1650 // iterate over departPosPersons
1651 for (const auto& departPosPerson : departPosPersons) {
1652 // obtain stack position and person
1653 const GNEEdge::StackPosition& personStackPosition = departPosPerson.first;
1654 GNEDemandElement* person = departPosPerson.second;
1655 // if stackedPersons is empty, add a new StackDemandElements
1656 if (stackedPersons.empty()) {
1657 stackedPersons.push_back(GNEEdge::StackDemandElements(personStackPosition, person));
1658 } else if (areStackPositionOverlapped(personStackPosition, stackedPersons.back().getStackPosition())) {
1659 // add new person to last inserted stackDemandElements
1660 stackedPersons[stackedPersons.size() - 1].addDemandElements(person);
1661 } else {
1662 // No overlapping, then add a new StackDemandElements
1663 stackedPersons.push_back(GNEEdge::StackDemandElements(personStackPosition, person));
1664 }
1665 }
1666 // iterate over stackedPersons
1667 for (const auto& person : stackedPersons) {
1668 // only update persons with one or more stack
1669 if (person.getDemandElements().size() > 1) {
1670 // set stack labels
1671 person.getDemandElements().front()->updateDemandElementStackLabel((int)person.getDemandElements().size());
1672 }
1673 }
1674 }
1675}
1676
1677
1678void
1680 // get lane containers map
1681 const std::map<const GNELane*, std::vector<GNEDemandElement*> > laneContainersMap = getContainersOverEdgeMap();
1682 // iterate over laneContainersMap and obtain a vector with
1683 for (const auto& containerMap : laneContainersMap) {
1684 // declare map for sort containers using their departpos+length position (StackPosition)
1685 std::vector<std::pair<GNEEdge::StackPosition, GNEDemandElement*> > departPosContainers;
1686 // declare vector of stack demand elements
1687 std::vector<GNEEdge::StackDemandElements> stackedContainers;
1688 // iterate over containers
1689 for (const auto& container : containerMap.second) {
1690 // get container's depart pos and length
1691 const double departPos = container->getAttributeDouble(SUMO_ATTR_DEPARTPOS);
1692 // make a stack position using departPos and length
1693 departPosContainers.push_back(std::make_pair(StackPosition(departPos, 1.8), container));
1694 // update depart element geometry
1695 container->updateDemandElementGeometry(containerMap.first, departPos);
1696 // reset container stack label
1697 container->updateDemandElementStackLabel(0);
1698 }
1699
1700 // sort departPosContainers
1701 std::sort(departPosContainers.begin(), departPosContainers.end());
1702 // iterate over departPosContainers
1703 for (const auto& departPosContainer : departPosContainers) {
1704 // obtain stack position and container
1705 const GNEEdge::StackPosition& containerStackPosition = departPosContainer.first;
1706 GNEDemandElement* container = departPosContainer.second;
1707 // if stackedContainers is empty, add a new StackDemandElements
1708 if (stackedContainers.empty()) {
1709 stackedContainers.push_back(GNEEdge::StackDemandElements(containerStackPosition, container));
1710 } else if (areStackPositionOverlapped(containerStackPosition, stackedContainers.back().getStackPosition())) {
1711 // add new container to last inserted stackDemandElements
1712 stackedContainers[stackedContainers.size() - 1].addDemandElements(container);
1713 } else {
1714 // No overlapping, then add a new StackDemandElements
1715 stackedContainers.push_back(GNEEdge::StackDemandElements(containerStackPosition, container));
1716 }
1717 }
1718 // iterate over stackedContainers
1719 for (const auto& container : stackedContainers) {
1720 // only update containers with one or more stack
1721 if (container.getDemandElements().size() > 1) {
1722 // set stack labels
1723 container.getDemandElements().front()->updateDemandElementStackLabel((int)container.getDemandElements().size());
1724 }
1725 }
1726 }
1727}
1728
1729
1730bool
1732 // calculate angle between both junction positions
1733 double edgeAngle = RAD2DEG(getFromJunction()->getPositionInView().angleTo2D(getToJunction()->getPositionInView()));
1734 // adjust to 360 degrees
1735 while (edgeAngle < 0) {
1736 edgeAngle += 360;
1737 }
1738 // fmod round towards zero which is not want we want for negative numbers
1739 edgeAngle = fmod(edgeAngle, 360);
1740 // check angle
1741 return edgeAngle >= 0 && edgeAngle < 180;
1742}
1743
1744
1745bool
1747 // get incoming edges
1748 const auto incomingEdges = getFromJunction()->getGNEIncomingEdges();
1749 // iterate over connections
1750 for (const auto& incomingEdge : incomingEdges) {
1751 for (const auto& connection : incomingEdge->getGNEConnections()) {
1752 if (connection->getEdgeTo() == this) {
1753 return true;
1754 }
1755 }
1756 }
1757 return false;
1758}
1759
1760
1761bool
1763 return (myGNEConnections.size() > 0);
1764}
1765
1766
1767GNEEdge*
1769 for (const auto& outgoingEdge : getParentJunctions().back()->getGNEOutgoingEdges()) {
1770 if (outgoingEdge->getToJunction() == getFromJunction()) {
1771 return outgoingEdge;
1772 }
1773 }
1774 return nullptr;
1775}
1776
1777// ===========================================================================
1778// private
1779// ===========================================================================
1780
1781GNEEdge::StackPosition::StackPosition(const double departPos, const double length) :
1782 pair(departPos, departPos + length) {
1783}
1784
1785
1786double
1788 return first;
1789}
1790
1791
1792double
1794 return second;
1795}
1796
1797
1799 pair(stackedPosition, {
1800 demandElement
1801}) {
1802}
1803
1804
1805void
1807 second.push_back(demandElement);
1808}
1809
1810
1813 return first;
1814}
1815
1816
1817const std::vector<GNEDemandElement*>&
1819 return second;
1820}
1821
1822
1823void
1824GNEEdge::setAttribute(SumoXMLAttr key, const std::string& value) {
1825 switch (key) {
1826 case SUMO_ATTR_ID:
1827 myNet->getAttributeCarriers()->updateEdgeID(this, value);
1828 // enable save demand elements if there are stops
1829 for (const auto& stop : getChildDemandElements()) {
1830 if (stop->getTagProperty()->isVehicleStop()) {
1832 }
1833 }
1834 // also for lanes
1835 for (const auto& lane : getChildLanes()) {
1836 for (const auto& stop : lane->getChildDemandElements()) {
1837 if (stop->getTagProperty()->isVehicleStop()) {
1839 }
1840 }
1841 }
1842 break;
1843 case SUMO_ATTR_FROM:
1844 myNet->changeEdgeEndpoints(this, value, getToJunction()->getID());
1845 // update this edge of list of outgoings edges of the old first parent junction
1847 // update first parent junction
1849 // update this edge of list of outgoings edges of the new first parent junction
1851 // update centering boundary and grid
1853 break;
1854 case SUMO_ATTR_TO:
1855 myNet->changeEdgeEndpoints(this, getFromJunction()->getID(), value);
1856 // update this edge of list of incomings edges of the old second parent junction
1858 // update second parent junction
1860 // update this edge of list of incomings edges of the new second parent junction
1862 // update centering boundary and grid
1864 break;
1865 case SUMO_ATTR_NUMLANES:
1866 throw InvalidArgument("GNEEdge::setAttribute (private) called for attr SUMO_ATTR_NUMLANES. This should never happen");
1867 case SUMO_ATTR_PRIORITY:
1868 myNBEdge->myPriority = parse<int>(value);
1869 break;
1870 case SUMO_ATTR_LENGTH:
1871 if (value.empty()) {
1873 } else {
1874 myNBEdge->setLoadedLength(parse<double>(value));
1875 }
1876 break;
1877 case SUMO_ATTR_TYPE:
1878 myNBEdge->myType = value;
1879 break;
1881 myNBEdge->myRoutingType = value;
1882 break;
1883 case SUMO_ATTR_SHAPE:
1884 // set new geometry
1885 setGeometry(parse<PositionVector>(value), true);
1886 // update centering boundary and grid
1888 break;
1891 break;
1892 case SUMO_ATTR_NAME:
1893 myNBEdge->setStreetName(value);
1894 break;
1895 case SUMO_ATTR_SPEED:
1896 myNBEdge->setSpeed(-1, parse<double>(value));
1897 break;
1898 case SUMO_ATTR_FRICTION:
1899 myNBEdge->setFriction(-1, parse<double>(value));
1900 break;
1901 case SUMO_ATTR_WIDTH:
1902 if (value.empty() || (value == "default")) {
1904 } else {
1905 myNBEdge->setLaneWidth(-1, parse<double>(value));
1906 }
1907 break;
1909 myNBEdge->setEndOffset(-1, parse<double>(value));
1910 break;
1911 case SUMO_ATTR_ALLOW:
1912 break; // no edge value
1913 case SUMO_ATTR_DISALLOW:
1914 break; // no edge value
1915 case SUMO_ATTR_DISTANCE:
1916 if (value.empty()) {
1917 myNBEdge->setDistance(0.0);
1918 } else {
1919 myNBEdge->setDistance(parse<double>(value));
1920 }
1921 break;
1923 myConnectionStatus = value;
1924 if (value == FEATURE_GUESSED) {
1927 } else if (value != FEATURE_GUESSED) {
1929 }
1930 break;
1931 case GNE_ATTR_SHAPE_START: {
1932 // get geometry of NBEdge, remove FIRST element with the new value (or with the Junction Source position) and set it back to edge
1933 Position newShapeStart;
1934 if (value == "") {
1935 newShapeStart = getFromJunction()->getNBNode()->getPosition();
1936 } else {
1937 newShapeStart = parse<Position>(value);
1938 }
1939 // set shape start position
1940 setShapeStartPos(newShapeStart);
1941 // update centering boundary and grid
1943 break;
1944 }
1945 case GNE_ATTR_SHAPE_END: {
1946 // get geometry of NBEdge, remove LAST element with the new value (or with the Junction Destination position) and set it back to edge
1947 Position newShapeEnd;
1948 if (value == "") {
1949 newShapeEnd = getToJunction()->getNBNode()->getPosition();
1950 } else {
1951 newShapeEnd = parse<Position>(value);
1952 }
1953 // set shape end position
1954 setShapeEndPos(newShapeEnd);
1955 // update centering boundary and grid
1957 break;
1958 }
1959 case GNE_ATTR_BIDIR:
1960 myNBEdge->setBidi(parse<bool>(value));
1961 break;
1963 if (value.empty()) {
1965 } else {
1966 myNBEdge->myEdgeStopOffset.setOffset(parse<double>(value));
1967 }
1968 break;
1971 break;
1972 default:
1973 setCommonAttribute(key, value);
1974 break;
1975 }
1976 // get template editor
1978 // check if update template (except for modification status)
1979 if (templateEditor->getEdgeTemplate() && (templateEditor->getEdgeTemplate()->getID() == getID()) &&
1982 }
1983 // invalidate demand path calculator
1985}
1986
1987
1988void
1989GNEEdge::setNumLanes(int numLanes, GNEUndoList* undoList) {
1990 // begin undo list
1991 undoList->begin(this, "change number of " + toString(SUMO_TAG_LANE) + "s");
1992 // invalidate logic of source/destination edges
1993 getFromJunction()->setLogicValid(false, undoList);
1994 getToJunction()->setLogicValid(false, undoList);
1995 // disable update geometry (see #6336)
1996 myUpdateGeometry = false;
1997 // remove edge from grid
1999 // save old number of lanes
2000 const int oldNumLanes = (int)getChildLanes().size();
2001 // get opposite ID
2002 const auto oppositeID = getChildLanes().back()->getAttribute(GNE_ATTR_OPPOSITE);
2003 if (oppositeID != "") {
2004 // we'll have a different leftmost lane after adding/removing lanes
2006 }
2007 for (int i = oldNumLanes; i < numLanes; i++) {
2008 // since the GNELane does not exist yet, it cannot have yet been referenced so we only pass a zero-pointer
2009 undoList->add(new GNEChange_Lane(this, myNBEdge->getLaneStruct(oldNumLanes - 1)), true);
2010 }
2011 for (int i = (oldNumLanes - 1); i > (numLanes - 1); i--) {
2012 myNet->deleteLane(getChildLanes().at(i), undoList, false);
2013 }
2014 if (oppositeID != "") {
2016 }
2017 // enable updateGeometry again
2018 myUpdateGeometry = true;
2019 // update geometry of entire edge
2021 // end undo list
2022 undoList->end();
2023 // update centering boundary (without updating RTREE)
2025 // insert edge in grid again
2027}
2028
2029
2030void
2031GNEEdge::updateFirstParentJunction(const std::string& value) {
2032 auto newJunction = myNet->getAttributeCarriers()->retrieveJunction(value);
2033 GNEHierarchicalElement::updateParent(this, 0, newJunction);
2034}
2035
2036
2037void
2038GNEEdge::updateSecondParentJunction(const std::string& value) {
2039 auto newJunction = myNet->getAttributeCarriers()->retrieveJunction(value);
2040 GNEHierarchicalElement::updateParent(this, 1, newJunction);
2041}
2042
2043
2044void
2045GNEEdge::addLane(GNELane* lane, const NBEdge::Lane& laneAttrs, bool recomputeConnections) {
2046 const int index = lane ? lane->getIndex() : myNBEdge->getNumLanes();
2047 // the laneStruct must be created first to ensure we have some geometry
2048 // unless the connections are fully recomputed, existing indices must be shifted
2049 myNBEdge->addLane(index, true, recomputeConnections, !recomputeConnections);
2050 if (lane) {
2051 // restore a previously deleted lane
2053 newParentLanes.insert(newParentLanes.begin() + index, lane);
2054 while (getChildLanes().size() > 0) {
2055 removeChild(this, getChildLanes().front());
2056 }
2057 for (const auto newParentLane : newParentLanes) {
2058 insertChild(this, newParentLane);
2059 }
2060 } else {
2061 // create a new lane by copying leftmost lane
2062 lane = new GNELane(this, index);
2064 }
2065 lane->incRef("GNEEdge::addLane");
2066 // add in attributeCarriers
2068 // check if lane is selected
2069 if (lane->isAttributeCarrierSelected()) {
2070 lane->selectAttributeCarrier();
2071 }
2072 // we copy all attributes except shape since this is recomputed from edge shape
2073 myNBEdge->setSpeed(lane->getIndex(), laneAttrs.speed);
2074 myNBEdge->setFriction(lane->getIndex(), laneAttrs.friction);
2075 myNBEdge->setPermissions(laneAttrs.permissions, lane->getIndex());
2077 myNBEdge->setEndOffset(lane->getIndex(), laneAttrs.endOffset);
2078 myNBEdge->setLaneWidth(lane->getIndex(), laneAttrs.width);
2079 // update indices
2080 for (int i = 0; i < (int)getChildLanes().size(); ++i) {
2081 getChildLanes()[i]->setIndex(i);
2082 }
2083 /* while technically correct, this looks ugly
2084 getFromJunction()->invalidateShape();
2085 getToJunction()->invalidateShape();
2086 */
2087 // Remake connections for this edge and all edges that target this lane
2089 // remake connections of all edges of junction source and destination
2090 for (const auto& fromEdge : getFromJunction()->getChildEdges()) {
2091 fromEdge->remakeGNEConnections();
2092 }
2093 // remake connections of all edges of junction source and destination
2094 for (const auto& toEdge : getToJunction()->getChildEdges()) {
2095 toEdge->remakeGNEConnections();
2096 }
2097 // Update geometry with the new lane
2099 // update boundary and grid
2101}
2102
2103
2104void
2105GNEEdge::removeLane(GNELane* lane, bool recomputeConnections) {
2106 if (getChildLanes().size() == 0) {
2107 throw ProcessError("Should not remove the last " + toString(SUMO_TAG_LANE) + " from an " + getTagStr());
2108 }
2109 if (lane == nullptr) {
2110 lane = getChildLanes().back();
2111 }
2112 // check if lane is selected
2113 if (lane->isAttributeCarrierSelected()) {
2115 }
2116 // before removing, check that lane isn't being inspected
2119 // Delete lane of edge's container
2120 // unless the connections are fully recomputed, existing indices must be shifted
2121 myNBEdge->deleteLane(lane->getIndex(), recomputeConnections, !recomputeConnections);
2122 lane->decRef("GNEEdge::removeLane");
2123 // delete lane from edge
2125 // remove from attributeCarriers
2127 // Delete lane if is unreferenced
2128 if (lane->unreferenced()) {
2129 delete lane;
2130 }
2131 // update indices
2132 for (int i = 0; i < (int)getChildLanes().size(); ++i) {
2133 getChildLanes()[i]->setIndex(i);
2134 }
2135 /* while technically correct, this looks ugly
2136 getFromJunction()->invalidateShape();
2137 getToJunction()->invalidateShape();
2138 */
2139 // Remake connections of this edge
2141 // remake connections of all edges of junction source and destination
2142 for (const auto& fromEdge : getFromJunction()->getChildEdges()) {
2143 fromEdge->remakeGNEConnections();
2144 }
2145 // remake connections of all edges of junction source and destination
2146 for (const auto& toEdge : getToJunction()->getChildEdges()) {
2147 toEdge->remakeGNEConnections();
2148 }
2149 // Update element
2151 // update boundary and grid
2153}
2154
2155
2156void
2157GNEEdge::addConnection(NBEdge::Connection nbCon, bool selectAfterCreation) {
2158 // If a new connection was successfully created
2160 nbCon.keepClear, nbCon.contPos, nbCon.visibility,
2161 nbCon.speed, nbCon.friction, nbCon.customLength, nbCon.customShape, nbCon.uncontrolled)) {
2162 // Create or retrieve existent GNEConnection
2163 GNEConnection* con = retrieveGNEConnection(nbCon.fromLane, nbCon.toEdge, nbCon.toLane);
2164 // add it to GNEConnection container
2165 myGNEConnections.push_back(con);
2166 // Add reference
2167 myGNEConnections.back()->incRef("GNEEdge::addConnection");
2168 // select GNEConnection if needed
2169 if (selectAfterCreation) {
2171 }
2172 // update geometry
2173 con->updateGeometry();
2174 }
2175 // actually we only do this to force a redraw
2177}
2178
2179
2180void
2182 // check if is a explicit turnaround
2183 if (nbCon.toEdge == myNBEdge->getTurnDestination()) {
2185 }
2186 // remove NBEdge::connection from NBEdge
2188 // remove their associated GNEConnection
2189 GNEConnection* connection = retrieveGNEConnection(nbCon.fromLane, nbCon.toEdge, nbCon.toLane, false);
2190 if (connection != nullptr) {
2191 // before removing, check that the connection isn't being inspected
2194 connection->decRef("GNEEdge::removeConnection");
2195 myGNEConnections.erase(std::find(myGNEConnections.begin(), myGNEConnections.end(), connection));
2196 // check if connection is selected
2197 if (connection->isAttributeCarrierSelected()) {
2198 connection->unselectAttributeCarrier();
2199 }
2200 // remove it from network
2201 myNet->removeGLObjectFromGrid(connection);
2202 // check if remove it from Attribute Carriers
2203 if (myNet->getAttributeCarriers()->getConnections().count(connection) > 0) {
2205 }
2206 if (connection->unreferenced()) {
2207 // actually we only do this to force a redraw
2209 }
2210 }
2211}
2212
2213
2215GNEEdge::retrieveGNEConnection(int fromLane, NBEdge* to, int toLane, bool createIfNoExist) {
2216 for (const auto& connection : myGNEConnections) {
2217 if ((connection->getFromLaneIndex() == fromLane) && (connection->getEdgeTo()->getNBEdge() == to) && (connection->getToLaneIndex() == toLane)) {
2218 return connection;
2219 }
2220 }
2221 if (createIfNoExist) {
2222 // create new connection. Will be added to the rTree on first geometry computation
2223 GNEConnection* connection = new GNEConnection(getChildLanes()[fromLane], myNet->getAttributeCarriers()->retrieveEdge(to->getID())->getChildLanes()[toLane]);
2224 // add it into network
2225 myNet->addGLObjectIntoGrid(connection);
2226 // add it in attributeCarriers
2228 return connection;
2229 } else {
2230 return nullptr;
2231 }
2232}
2233
2234
2235void
2236GNEEdge::setEdgeID(const std::string& newID) {
2237 setNetworkElementID(newID);
2238 for (const auto& lane : getChildLanes()) {
2239 lane->setNetworkElementID(getNBEdge()->getLaneID(lane->getIndex()));
2240 }
2241}
2242
2243
2244bool
2246 for (const auto& lane : getChildLanes()) {
2247 if (lane->isRestricted(vclass)) {
2248 return true;
2249 }
2250 }
2251 return false;
2252}
2253
2254
2255void
2257 // Remove all crossings that contain this edge in parameter "edges"
2258 for (const auto& crossing : junction->getGNECrossings()) {
2259 if (crossing->checkEdgeBelong(this)) {
2260 myNet->deleteCrossing(crossing, undoList);
2261 }
2262 }
2263}
2264
2265
2266void
2271 PositionVector innerShape(modifiedShape.begin() + 1, modifiedShape.end() - 1);
2272 setAttribute(SUMO_ATTR_SHAPE, toString(innerShape), undoList);
2273}
2274
2275
2277GNEEdge::smoothShape(const PositionVector& old, bool forElevation) {
2278 const auto& neteditOptions = OptionsCont::getOptions();
2279 // distinguish 3 cases:
2280 // a) if the edge has exactly 3 or 4 points, use these as control points
2281 // b) if the edge has more than 4 points, use the first 2 and the last 2 as control points
2282 // c) if the edge is straight and both nodes are geometry-like nodes, use geometry of the continuation edges as control points
2283 PositionVector init;
2284#ifdef DEBUG_SMOOTH_GEOM
2285 if (DEBUGCOND(this)) std::cout << getID()
2286 << " forElevation=" << forElevation
2287 << " fromGeometryLike=" << myNBEdge->getFromNode()->geometryLike()
2288 << " toGeometryLike=" << myNBEdge->getToNode()->geometryLike()
2289 << " smoothShape old=" << old << "\n";
2290#endif
2291 if (old.size() == 3 || old.size() == 4) {
2292 init = old;
2293 } else if (old.size() > 4 && !forElevation) {
2294 // for elevation, the initial segments are not useful
2295 init.push_back(old[0]);
2296 init.push_back(old[1]);
2297 init.push_back(old[-2]);
2298 init.push_back(old[-1]);
2299 } else if (myNBEdge->getFromNode()->geometryLike() && myNBEdge->getToNode()->geometryLike()) {
2300 PositionVector begShape;
2301 PositionVector endShape;
2302 const EdgeVector& incoming = myNBEdge->getFromNode()->getIncomingEdges();
2303 const EdgeVector& outgoing = myNBEdge->getToNode()->getOutgoingEdges();
2304 if (incoming.size() == 1) {
2305 begShape = incoming[0]->getGeometry();
2306 } else {
2307 assert(incoming.size() == 2);
2308 begShape = myNBEdge->isTurningDirectionAt(incoming[0]) ? incoming[1]->getGeometry() : incoming[0]->getGeometry();
2309 }
2310 if (outgoing.size() == 1) {
2311 endShape = outgoing[0]->getGeometry();
2312 } else {
2313 assert(outgoing.size() == 2);
2314 endShape = myNBEdge->isTurningDirectionAt(outgoing[0]) ? outgoing[1]->getGeometry() : outgoing[0]->getGeometry();
2315 }
2316 const double dist = MIN2(old.length2D(), MAX2(old.length2D() / 8, fabs(old[0].z() - old[-1].z()) * OptionsCont::getOptions().getFloat("geometry.max-grade") / 3));
2317 if (forElevation) {
2318 // initialize control point elevation for smooth continuation
2319 init.push_back(old[0]);
2320 init.push_back(old.positionAtOffset2D(dist));
2321 init.push_back(old.positionAtOffset2D(old.length2D() - dist));
2322 init.push_back(old[-1]);
2323 double begZ = begShape.positionAtOffset2D(MAX2(0.0, begShape.length2D() - dist)).z();
2324 double endZ = endShape.positionAtOffset2D(MIN2(begShape.length2D(), dist)).z();
2325 // continue incline
2326 init[1].setz(2 * init[0].z() - begZ);
2327 init[2].setz(2 * init[-1].z() - endZ);
2328 } else {
2329 bool ok = true;
2330 const double straightThresh = DEG2RAD(neteditOptions.getFloat("opendrive-output.straight-threshold"));
2331 init = NBNode::bezierControlPoints(begShape, endShape, false, dist, dist, ok, nullptr, straightThresh);
2332 }
2333#ifdef DEBUG_SMOOTH_GEOM
2334 if (DEBUGCOND(this)) {
2335 std::cout << " begShape=" << begShape << " endShape=" << endShape << " forElevation=" << forElevation << " dist=" << dist << " ok=" << ok << " init=" << init << "\n";
2336 }
2337#endif
2338 }
2339 if (init.size() == 0) {
2340 return PositionVector::EMPTY;
2341 } else {
2342 const int numPoints = MAX2(neteditOptions.getInt("junctions.internal-link-detail"),
2343 int(old.length2D() / neteditOptions.getFloat("opendrive.curve-resolution")));
2344 return init.bezier(numPoints);
2345 }
2346}
2347
2348
2349void
2351 PositionVector modifiedShape = smoothShape(myNBEdge->getGeometry(), false);
2352 if (modifiedShape.size() < 2) {
2353 WRITE_WARNINGF(TL("Could not compute smooth shape for edge '%'"), getID());
2354 } else {
2355 PositionVector innerShape(modifiedShape.begin() + 1, modifiedShape.end() - 1);
2356 setAttribute(SUMO_ATTR_SHAPE, toString(innerShape), undoList);
2357 }
2358}
2359
2360
2361void
2363 PositionVector elevationBase;
2364 for (const Position& pos : myNBEdge->getGeometry()) {
2365 if (elevationBase.size() == 0 || elevationBase[-1].z() != pos.z()) {
2366 elevationBase.push_back(pos);
2367 }
2368 }
2369 PositionVector elevation = smoothShape(elevationBase, true);
2370 if (elevation.size() <= 2) {
2371 WRITE_WARNINGF(TL("Could not compute smooth elevation for edge '%'"), getID());
2372 } else {
2373 PositionVector modifiedShape = myNBEdge->getGeometry();
2374 if (modifiedShape.size() < 5) {
2375 modifiedShape = modifiedShape.resample(OptionsCont::getOptions().getFloat("opendrive.curve-resolution"), false);
2376 }
2377 const double scale = elevation.length2D() / modifiedShape.length2D();
2378 //std::cout << " elevation=" << elevation << "\n mod1=" << modifiedShape << " scale=" << scale << "\n";
2379 double seen = 0;
2380 for (int i = 1; i < (int)modifiedShape.size(); ++i) {
2381 seen += modifiedShape[i - 1].distanceTo2D(modifiedShape[i]);
2382 modifiedShape[i].setz(elevation.positionAtOffset2D(seen * scale).z());
2383 }
2384 //std::cout << " mod2=" << modifiedShape << "\n";
2385 PositionVector innerShape(modifiedShape.begin() + 1, modifiedShape.end() - 1);
2386 setAttribute(SUMO_ATTR_SHAPE, toString(innerShape), undoList);
2387 }
2388}
2389
2390
2391void
2393 // remove start position and add it the new position
2395 geom.pop_front();
2396 geom.push_front(pos);
2397 // restore modified shape
2398 setGeometry(geom, false);
2399}
2400
2401
2402void
2404 // remove end position and add it the new position
2406 geom.pop_back();
2407 geom.push_back(pos);
2408 // restore modified shape
2409 setGeometry(geom, false);
2410}
2411
2412
2413const std::map<const GNELane*, std::vector<GNEDemandElement*> >
2415 // declare vehicles over edge vector
2416 std::vector<GNEDemandElement*> vehiclesOverEdge;
2417 // declare solution map
2418 std::map<const GNELane*, std::vector<GNEDemandElement*> > vehiclesOverEdgeMap;
2419 // declare a set of vehicles (to avoid duplicates)
2420 std::set<std::pair<double, GNEDemandElement*> > vehicles;
2421 // first obtain all vehicles of this edge
2422 for (const auto& edgeChild : getChildDemandElements()) {
2423 if (((edgeChild->getTagProperty()->getTag() == SUMO_TAG_TRIP) || (edgeChild->getTagProperty()->getTag() == SUMO_TAG_FLOW)) &&
2424 (edgeChild->getParentEdges().front() == this)) {
2425 vehicles.insert(std::make_pair(edgeChild->getAttributeDouble(SUMO_ATTR_DEPART), edgeChild));
2426 vehicles.insert(std::make_pair(edgeChild->getAttributeDouble(SUMO_ATTR_DEPART), edgeChild));
2427 } else if ((edgeChild->getTagProperty()->getTag() == SUMO_TAG_ROUTE) && (edgeChild->getParentEdges().front() == this)) {
2428 for (const auto& routeChild : edgeChild->getChildDemandElements()) {
2429 if (routeChild->getTagProperty()->vehicleRoute()) {
2430 vehicles.insert(std::make_pair(routeChild->getAttributeDouble(SUMO_ATTR_DEPART), routeChild));
2431 }
2432 }
2433 } else if ((edgeChild->getTagProperty()->getTag() == GNE_TAG_ROUTE_EMBEDDED) && (edgeChild->getParentEdges().front() == this) && (edgeChild->getParentDemandElements().size() > 0)) {
2434 vehicles.insert(std::make_pair(edgeChild->getParentDemandElements().front()->getAttributeDouble(SUMO_ATTR_DEPART), edgeChild->getParentDemandElements().front()));
2435 }
2436 }
2437 // reserve
2438 vehiclesOverEdge.reserve(vehicles.size());
2439 // iterate over vehicles
2440 for (const auto& vehicle : vehicles) {
2441 // add it over vehiclesOverEdge;
2442 vehiclesOverEdge.push_back(vehicle.second);
2443 }
2444 // now split vehicles by lanes
2445 for (const auto& vehicle : vehiclesOverEdge) {
2446 const GNELane* vehicleLane = vehicle->getFirstPathLane();
2447 if (vehicleLane) {
2448 vehiclesOverEdgeMap[vehicleLane].push_back(vehicle);
2449 }
2450 }
2451 return vehiclesOverEdgeMap;
2452}
2453
2454
2455const std::map<const GNELane*, std::vector<GNEDemandElement*> >
2457 // declare persons over edge vector
2458 std::vector<GNEDemandElement*> personsOverEdge;
2459 // declare solution map
2460 std::map<const GNELane*, std::vector<GNEDemandElement*> > personsOverEdgeMap;
2461 // declare a set of persons (to avoid duplicates)
2462 std::set<std::pair<double, GNEDemandElement*> > persons;
2463 // first obtain all persons of this edge
2464 for (const auto& edgeChild : getChildDemandElements()) {
2465 if (edgeChild->getTagProperty()->isPlanPerson() && (edgeChild->getParentDemandElements().size() > 0)) {
2466 persons.insert(std::make_pair(edgeChild->getParentDemandElements().front()->getAttributeDouble(SUMO_ATTR_DEPARTPOS), edgeChild->getParentDemandElements().front()));
2467 }
2468 }
2469 // reserve
2470 personsOverEdge.reserve(persons.size());
2471 // iterate over persons
2472 for (const auto& person : persons) {
2473 // add it over personsOverEdge;
2474 personsOverEdge.push_back(person.second);
2475 }
2476 // now split persons by lanes
2477 for (const auto& person : personsOverEdge) {
2478 const GNELane* personLane = person->getFirstPathLane();
2479 if (personLane) {
2480 personsOverEdgeMap[personLane].push_back(person);
2481 }
2482 }
2483 return personsOverEdgeMap;
2484}
2485
2486
2487
2488const std::map<const GNELane*, std::vector<GNEDemandElement*> >
2490 // declare containers over edge vector
2491 std::vector<GNEDemandElement*> containersOverEdge;
2492 // declare solution map
2493 std::map<const GNELane*, std::vector<GNEDemandElement*> > containersOverEdgeMap;
2494 // declare a set of containers (to avoid duplicates)
2495 std::set<std::pair<double, GNEDemandElement*> > containers;
2496 // first obtain all containers of this edge
2497 for (const auto& edgeChild : getChildDemandElements()) {
2498 if (edgeChild->getTagProperty()->isPlanContainer() && (edgeChild->getParentDemandElements().size() > 0)) {
2499 containers.insert(std::make_pair(edgeChild->getParentDemandElements().front()->getAttributeDouble(SUMO_ATTR_DEPARTPOS), edgeChild->getParentDemandElements().front()));
2500 }
2501 }
2502 // reserve
2503 containersOverEdge.reserve(containers.size());
2504 // iterate over containers
2505 for (const auto& container : containers) {
2506 // add it over containersOverEdge;
2507 containersOverEdge.push_back(container.second);
2508 }
2509 // now split containers by lanes
2510 for (const auto& container : containersOverEdge) {
2511 const GNELane* containerLane = container->getFirstPathLane();
2512 if (containerLane) {
2513 containersOverEdgeMap[containerLane].push_back(container);
2514 }
2515 }
2516 return containersOverEdgeMap;
2517}
2518
2519
2520void
2522 // first check conditions
2524 // check if draw geometry points
2525 const bool bigGeometryPoints = drawBigGeometryPoints();
2526 // Obtain exaggeration of the draw
2527 const double exaggeration = getExaggeration(s);
2528 // get geometry point radius
2529 const double geometryPointRadius = getGeometryPointRadius();
2530 // obtain geometry point color
2531 RGBColor geometryPointColor = s.junctionColorer.getSchemes()[0].getColor(2);
2532 if (drawUsingSelectColor() && s.laneColorer.getActive() != 1) {
2533 // override with special colors (unless the color scheme is based on selection)
2534 geometryPointColor = s.colorSettings.selectedEdgeColor.changedBrightness(-20);
2535 }
2536 // draw geometry points except initial and final
2537 for (int i = 1; i < (int)myNBEdge->getGeometry().size() - 1; i++) {
2538 // obtain geometry point
2539 const auto geometryPointPos = myNBEdge->getGeometry()[i];
2540 // push geometry point drawing matrix
2542 // set color
2543 GLHelper::setColor(geometryPointColor);
2544 // move geometry point geometryPointPos
2545 glTranslated(geometryPointPos.x(), geometryPointPos.y(), bigGeometryPoints ? GLO_GEOMETRYPOINT : GLO_LANE + 1);
2546 // draw filled circle (resolution of drawn circle depending of the zoom, to improve smoothness)
2547 GLHelper::drawFilledCircleDetailled(d, geometryPointRadius);
2548 // draw elevation or special symbols (Start, End and Block)
2550 // Translate to top
2551 glTranslated(0, 0, 0.2);
2552 // draw Z value
2553 GLHelper::drawText(toString(geometryPointPos.z()), Position(), 0, s.edgeValue.scaledSize(s.scale) / 2, s.edgeValue.color);
2554 }
2555 // pop geometry point drawing matrix
2557 }
2558 // draw start and end points
2559 if (bigGeometryPoints) {
2560 drawStartGeometryPoint(s, d, geometryPointRadius, layer, exaggeration);
2561 drawEndGeometryPoint(s, d, geometryPointRadius, layer, exaggeration);
2562 }
2563 // draw dotted contour geometry points
2566 }
2567}
2568
2569
2570void
2572 const double geometryPointRadius, const double layer, const double exaggeration) const {
2573 // check detail level
2575 // get first geometry point
2576 const auto& startGeometryPointPos = myNBEdge->getGeometry().front();
2577 // get flags
2578 const bool startPosEdited = (startGeometryPointPos != getParentJunctions().front()->getPositionInView());
2580 // check drawing conditions
2581 if (startPosEdited || forceDraw) {
2582 // calculate angle betwen first and second geometry point
2583 const double angle = RAD2DEG(startGeometryPointPos.angleTo2D(myNBEdge->getGeometry()[1])) * -1;
2584 // get selected geometry points
2585 const auto selectedGeometryPoints = gViewObjectsHandler.getSelectedGeometryPoints(this);
2586 // override with special colors (unless the color scheme is based on selection)
2587 if (drawUsingSelectColor() && s.laneColorer.getActive() != 1) {
2589 } else {
2590 GLHelper::setColor(s.junctionColorer.getSchemes()[0].getColor(2));
2591 }
2592 // push drawing matrix
2594 // move to point position
2595 glTranslated(startGeometryPointPos.x(), startGeometryPointPos.y(), GLO_GEOMETRYPOINT);
2596 // resolution of drawn circle depending of detail
2597 GLHelper::drawFilledCircleDetailled(d, geometryPointRadius, angle + 90, angle + 270);
2598 // pop drawing matrix
2600 // draw a "s" over last point depending of detail level
2602 // push drawing matrix
2604 // move top
2605 glTranslated(0, 0, GLO_GEOMETRYPOINT + 0.1);
2606 // draw S
2607 GLHelper::drawText("S", startGeometryPointPos, 0, geometryPointRadius, RGBColor(0, 50, 255));
2608 // pop drawing matrix
2610 // check if draw line between junctions
2611 if ((selectedGeometryPoints.size() > 0) && (selectedGeometryPoints.front() == 0)) {
2612 // set base color
2614 // push drawing matrix
2616 // draw line between geometry point and from junction
2617 const PositionVector lineA = {startGeometryPointPos, getFromJunction()->getNBNode()->getPosition()};
2618 GLHelper::drawBoxLine(lineA[1], RAD2DEG(lineA[0].angleTo2D(lineA[1])) - 90, lineA[0].distanceTo2D(lineA[1]), .1);
2619 // draw line between begin point of last lane shape and the first edge shape point
2620 const PositionVector lineB = {startGeometryPointPos, myNBEdge->getLanes().back().shape.front()};
2621 GLHelper::drawBoxLine(lineB[1], RAD2DEG(lineB[0].angleTo2D(lineB[1])) - 90, lineB[0].distanceTo2D(lineB[1]), .1);
2622 // pop drawing matrix
2624 }
2625 }
2626 // draw dotted contour geometry points
2628 geometryPointRadius, exaggeration);
2629 }
2630 }
2631}
2632
2633
2634void
2636 const double geometryPointRadius, const double layer, const double exaggeration) const {
2637 // check detail level
2639 // get first geometry point
2640 const auto& geometryPointPos = myNBEdge->getGeometry().back();
2641 // get flags
2642 const bool endPosEdited = (geometryPointPos != getParentJunctions().back()->getPositionInView());
2644 // check drawing conditions
2645 if (endPosEdited || forceDraw) {
2646 // calculate angle last and previous geometry point
2647 const double angle = RAD2DEG(geometryPointPos.angleTo2D(myNBEdge->getGeometry()[-2])) * -1;
2648 // get selected geometry points
2649 const auto selectedGeometryPoints = gViewObjectsHandler.getSelectedGeometryPoints(this);
2650 // override with special colors (unless the color scheme is based on selection)
2651 if (drawUsingSelectColor() && s.laneColorer.getActive() != 1) {
2653 } else {
2654 GLHelper::setColor(s.junctionColorer.getSchemes()[0].getColor(2));
2655 }
2656 // push drawing matrix
2658 // move to point position
2659 glTranslated(geometryPointPos.x(), geometryPointPos.y(), GLO_GEOMETRYPOINT);
2660 // resolution of drawn circle depending of detail
2661 GLHelper::drawFilledCircleDetailled(d, geometryPointRadius, angle + 90, angle + 270);
2662 // pop drawing matrix
2664 // draw a "s" over last point depending of detail level
2666 // push drawing matrix
2668 // move top
2669 glTranslated(0, 0, GLO_GEOMETRYPOINT + 0.1);
2670 // draw S
2671 GLHelper::drawText("E", geometryPointPos, 0, geometryPointRadius, RGBColor(0, 50, 255));
2672 // pop drawing matrix
2674 // check if draw line between junctions
2675 if ((selectedGeometryPoints.size() > 0) && (selectedGeometryPoints.back() == ((int)myNBEdge->getGeometry().size() - 1))) {
2676 // set base color
2678 // push drawing matrix
2680 // draw line between geometry point and from junction
2681 const PositionVector lineA = {geometryPointPos, getToJunction()->getNBNode()->getPosition()};
2682 GLHelper::drawBoxLine(lineA[1], RAD2DEG(lineA[0].angleTo2D(lineA[1])) - 90, lineA[0].distanceTo2D(lineA[1]), .1);
2683 // draw line between begin point of last lane shape and the first edge shape point
2684 const PositionVector lineB = {geometryPointPos, myNBEdge->getLanes().back().shape.back()};
2685 GLHelper::drawBoxLine(lineB[1], RAD2DEG(lineB[0].angleTo2D(lineB[1])) - 90, lineB[0].distanceTo2D(lineB[1]), .1);
2686 // pop drawing matrix
2688 }
2689 }
2690 // draw dotted contour geometry points
2692 geometryPointRadius, exaggeration);
2693 }
2694 }
2695}
2696
2697
2698void
2700 // draw the name and/or the street name
2701 const bool drawStreetName = s.streetName.show(this) && (myNBEdge->getStreetName() != "");
2702 const bool spreadSuperposed = s.spreadSuperposed && myNBEdge->getBidiEdge() != nullptr;
2703 // check conditions
2704 if (s.edgeName.show(this) || drawStreetName || s.edgeValue.show(this)) {
2705 // get first and last lanes
2706 const GNELane* firstLane = getChildLanes()[0];
2707 const GNELane* lastLane = getChildLanes()[getChildLanes().size() - 1];
2708 // calculate draw position
2709 Position drawPosition = firstLane->getLaneShape().positionAtOffset(firstLane->getLaneShape().length() / (double) 2.);
2710 drawPosition.add(lastLane->getLaneShape().positionAtOffset(lastLane->getLaneShape().length() / (double) 2.));
2711 drawPosition.mul(.5);
2712 if (spreadSuperposed) {
2713 // move name to the right of the edge and towards its beginning
2714 const double dist = 0.6 * s.edgeName.scaledSize(s.scale);
2715 const double shiftA = firstLane->getLaneShape().rotationAtOffset(firstLane->getLaneShape().length() / (double) 2.) - DEG2RAD(135);
2716 const Position shift(dist * cos(shiftA), dist * sin(shiftA));
2717 drawPosition.add(shift);
2718 }
2719 // calculate drawing angle
2720 double drawAngle = firstLane->getLaneShape().rotationDegreeAtOffset(firstLane->getLaneShape().length() / (double) 2.);
2721 drawAngle += 90;
2722 // avoid draw inverted text
2723 if (drawAngle > 90 && drawAngle < 270) {
2724 drawAngle -= 180;
2725 }
2726 // draw edge name
2727 if (s.edgeName.show(this)) {
2728 drawName(drawPosition, s.scale, s.edgeName, drawAngle);
2729 }
2730 // draw street name
2731 if (drawStreetName) {
2732 GLHelper::drawTextSettings(s.streetName, myNBEdge->getStreetName(), drawPosition, s.scale, drawAngle);
2733 }
2734 // draw edge values
2735 if (s.edgeValue.show(this)) {
2736 // get current scheme
2737 const int activeScheme = s.laneColorer.getActive();
2738 // calculate value depending of active scheme
2739 std::string value;
2740 if (activeScheme == 12) {
2741 // edge param, could be non-numerical
2742 value = getNBEdge()->getParameter(s.edgeParam, "");
2743 } else if (activeScheme == 13) {
2744 // lane param, could be non-numerical
2745 value = getNBEdge()->getLaneStruct(lastLane->getIndex()).getParameter(s.laneParam, "");
2746 } else {
2747 // use numerical value value of leftmost lane to hopefully avoid sidewalks, bikelanes etc
2748 const double doubleValue = lastLane->getColorValue(s, activeScheme);
2749 const RGBColor color = s.laneColorer.getScheme().getColor(doubleValue);
2750 value = color.alpha() == 0 ? "" : toString(doubleValue);
2751 }
2752 // check if value is empty
2753 if (value != "") {
2754 GLHelper::drawTextSettings(s.edgeValue, value, drawPosition, s.scale, drawAngle);
2755 }
2756 }
2757 }
2758}
2759
2760
2761void
2763 // draw geometry only if we'rent in drawForObjectUnderCursor mode
2765 // Push stopOffset matrix
2767 // translate to front (note: Special case)
2768 drawInLayer(layer + 1);
2770 for (const auto& lane : getChildLanes()) {
2771 lane->drawLaneStopOffset(s);
2772 }
2773 }
2774 // Push stopOffset matrix
2776 }
2777}
2778
2779
2780void
2782 // draw child additional
2783 for (const auto& additional : getChildAdditionals()) {
2784 if (!additional->getTagProperty()->isListedElement()) {
2785 additional->drawGL(s);
2786 }
2787 }
2788 // draw person stops
2790 for (const auto& stopEdge : getChildDemandElements()) {
2791 if ((stopEdge->getTagProperty()->getTag() == GNE_TAG_STOPPERSON_EDGE) || (stopEdge->getTagProperty()->getTag() == GNE_TAG_STOPCONTAINER_EDGE)) {
2792 stopEdge->drawGL(s);
2793 }
2794 }
2795 }
2796 // draw vehicles
2797 const std::map<const GNELane*, std::vector<GNEDemandElement*> > vehiclesMap = getVehiclesOverEdgeMap();
2798 for (const auto& vehicleMap : vehiclesMap) {
2799 for (const auto& vehicle : vehicleMap.second) {
2800 vehicle->drawGL(s);
2801 }
2802 }
2803 // draw TAZ elements
2804 drawTAZElements(s);
2805}
2806
2807
2808void
2810 // if we're selecting using a boundary, first don't calculate contour bt check if edge boundary is within selection boundary
2812 // simply add object in ViewObjectsHandler with full boundary
2813 gViewObjectsHandler.selectObject(this, layer, false, nullptr);
2814 } else {
2815 // get geometry point radius
2816 const auto geometryPointRadius = getGeometryPointRadius();
2817 // check if edit extrems
2818 const bool forceDrawExtrems = myNet->getViewParent()->getMoveFrame()->getNetworkMoveOptions()->getForceDrawGeometryPoints();
2819 const bool firstExtrem = forceDrawExtrems || (myNBEdge->getGeometry().front() != getParentJunctions().front()->getPositionInView());
2820 const bool lastExtrem = forceDrawExtrems || (myNBEdge->getGeometry().back() != getParentJunctions().back()->getPositionInView());
2821 // check if we're in move mode
2823 // calculate contour
2824 myNetworkElementContour.calculateContourEdge(s, d, this, this, layer, true, true);
2825 // calculate edge geometry points
2826 myNetworkElementContour.calculateContourEdgeGeometryPoints(s, d, this, geometryPointRadius, moveMode, firstExtrem, lastExtrem);
2827 }
2828}
2829
2830
2831void
2833 // first check if draw TAZ Elements is enabled
2835 if (getChildTAZSourceSinks().size() > 0) {
2836 // check if TAZ Source/sink is selected
2837 bool selected = false;
2838 for (const auto& TAZSourceSink : getChildTAZSourceSinks()) {
2839 if (TAZSourceSink->isAttributeCarrierSelected()) {
2840 selected = true;
2841 }
2842 }
2843 // iterate over lanes
2844 for (const auto& lane : getChildLanes()) {
2845 // Push layer matrix
2847 // translate to front (note: Special case)
2848 if (myDrawInFront) {
2849 glTranslated(0, 0, GLO_FRONTELEMENT);
2850 } else if (lane->getLaneShape().length2D() <= (s.neteditSizeSettings.junctionBubbleRadius * 2)) {
2852 } else {
2854 }
2855 // move to front
2856 glTranslated(0, 0, 0.1);
2857 // set color
2858 if (selected) {
2860 } else {
2862 }
2863 // draw as box lines
2865 lane->getDrawingConstants()->getDrawingWidth());
2866 // Pop layer matrix
2868 }
2869 /*
2870 // check if curently we're inspecting a TAZ Source/Sink
2871 for (const auto& TAZSourceSink : TAZSourceSinks) {
2872 if (myNet->getViewNet()->isAttributeCarrierInspected(TAZSourceSink)) {
2873 drawDottedContourEdge(s, GUIDottedGeometry::DottedContourType::INSPECT, this, true, true);
2874 } else if (TAZSourceSink == markAC) {
2875 drawDottedContourEdge(s, GUIDottedGeometry::DottedContourType::FRONT, this, true, true);
2876 }
2877 }
2878 */
2879 }
2880 }
2881}
2882
2883
2884void
2886 // avoid draw for railways
2887 if ((d <= GUIVisualizationSettings::Detail::LaneDetails) && !getChildLanes().front()->getDrawingConstants()->drawAsRailway() &&
2889 // push draw matrix
2891 // translate to front depending of big points
2892 if (drawBigGeometryPoints()) {
2893 glTranslated(0, 0, GLO_GEOMETRYPOINT - 1);
2894 } else {
2895 glTranslated(0, 0, layer);
2896 }
2897 // obtain color
2898 RGBColor geometryPointColor = s.junctionColorer.getSchemes()[0].getColor(2);
2899 if (drawUsingSelectColor() && s.laneColorer.getActive() != 1) {
2900 // override with special colors (unless the color scheme is based on selection)
2901 geometryPointColor = s.colorSettings.selectedEdgeColor.changedBrightness(-20);
2902 }
2903 // never draw when at full transparency
2904 if (geometryPointColor.alpha() != 0) {
2905 // set color
2906 GLHelper::setColor(geometryPointColor);
2907 // iterate over NBEdge geometry
2908 for (int i = 1; i < (int)myNBEdge->getGeometry().size(); i++) {
2909 // calculate line between previous and current geometry point
2910 PositionVector line = {myNBEdge->getGeometry()[i - 1], myNBEdge->getGeometry()[i]};
2911 line.move2side(0.2);
2912 // draw box line
2913 GLHelper::drawBoxLine(line[1], RAD2DEG(line[0].angleTo2D(line[1])) - 90, line[0].distanceTo2D(line[1]), .1);
2914 }
2915 }
2916 // pop draw matrix
2918 }
2919}
2920
2921
2922bool
2924 // get edit modes
2925 const auto& editModes = myNet->getViewNet()->getEditModes();
2926 // continue depending of conditions
2927 if (!editModes.isCurrentSupermodeNetwork()) {
2928 return false;
2929 } else if (editModes.networkEditMode == NetworkEditMode::NETWORK_MOVE) {
2930 return true;
2931 } else if ((editModes.networkEditMode == NetworkEditMode::NETWORK_DELETE) &&
2933 return true;
2934 } else {
2935 return false;
2936 }
2937}
2938
2939
2940bool
2942 if ((vehicleA.beginPosition() == vehicleB.beginPosition()) && (vehicleA.endPosition() == vehicleB.endPosition())) {
2943 return true;
2944 } else if ((vehicleA.beginPosition() < vehicleB.beginPosition()) && (vehicleA.endPosition() > vehicleB.endPosition())) {
2945 return true;
2946 } else if ((vehicleA.beginPosition() < vehicleB.beginPosition()) && (vehicleA.endPosition() > vehicleB.beginPosition())) {
2947 return true;
2948 } else if ((vehicleA.beginPosition() < vehicleB.endPosition()) && (vehicleA.endPosition() > vehicleB.endPosition())) {
2949 return true;
2950 } else {
2951 return false;
2952 }
2953}
2954
2955
2956double
2960
2961/****************************************************************************/
#define VEHICLE_GAP
Definition GNEEdge.cpp:62
std::vector< ChildType > GNEHierarchicalContainerChildren
#define ENDPOINT_TOLERANCE
@ NETWORK_DELETE
mode for deleting network elements
@ NETWORK_MOVE
mode for moving network elements
@ NETWORK_ADDITIONAL
Mode for editing additionals.
@ NETWORK_SELECT
mode for selecting network elements
@ DEMAND_PERSONPLAN
Mode for editing person plan.
@ DEMAND_CONTAINER
Mode for editing container.
@ DEMAND_PERSON
Mode for editing person.
@ DEMAND_VEHICLE
Mode for editing vehicles.
@ DEMAND_CONTAINERPLAN
Mode for editing container plan.
@ GLO_JUNCTION
a junction
@ GLO_FRONTELEMENT
front element (used in netedit)
@ GLO_LANE
a lane
@ GLO_GEOMETRYPOINT
geometry point (used in netedit)
@ GLO_EDGE
an edge
GUIViewObjectsHandler gViewObjectsHandler
#define DEG2RAD(x)
Definition GeomHelper.h:35
#define RAD2DEG(x)
Definition GeomHelper.h:36
#define DEBUGCOND(PED)
#define WRITE_WARNINGF(...)
Definition MsgHandler.h:287
#define TL(string)
Definition MsgHandler.h:304
#define TLF(string,...)
Definition MsgHandler.h:306
std::vector< NBEdge * > EdgeVector
container for (sorted) edges
Definition NBCont.h:42
const SVCPermissions SVCAll
all VClasses are allowed
SVCPermissions invertPermissions(SVCPermissions permissions)
negate the given permissions and ensure that only relevant bits are set
const std::string & getVehicleClassNames(SVCPermissions permissions, bool expand)
Returns the ids of the given classes, divided using a ' '.
bool canParseVehicleClasses(const std::string &classes)
Checks whether the given string contains only known vehicle classes.
SUMOVehicleClass
Definition of vehicle classes to differ between different lane usage and authority types.
@ SVC_PASSENGER
vehicle is a passenger car (a "normal" car)
@ SUMO_TAG_TAZ
a traffic assignment zone
@ GNE_TAG_STOPCONTAINER_EDGE
@ SUMO_TAG_LANETYPE
lane type
@ SUMO_TAG_FLOW
a flow definition using from and to edges or a route
@ SUMO_TAG_ROUTE
description of a route
@ SUMO_TAG_LANE
begin/end of the description of a single lane
@ SUMO_TAG_TYPE
type (edge)
@ GNE_TAG_ROUTE_EMBEDDED
embedded route
@ GNE_TAG_STOPPERSON_EDGE
@ SUMO_TAG_TRIP
a single trip definition (used by router)
@ SUMO_TAG_EDGE
begin/end of the description of an edge
SumoXMLAttr
Numbers representing SUMO-XML - attributes.
@ SUMO_ATTR_DISALLOW
@ SUMO_ATTR_ALLOW
@ SUMO_ATTR_DEPART
@ SUMO_ATTR_FROM_JUNCTION
@ SUMO_ATTR_SPEED
@ GNE_ATTR_STOPOFFSET
stop offset (virtual, used by edge and lanes)
@ GNE_ATTR_OPPOSITE
to busStop (used by personPlans)
@ SUMO_ATTR_TO_JUNCTION
@ GNE_ATTR_PARAMETERS
parameters "key1=value1|key2=value2|...|keyN=valueN"
@ SUMO_ATTR_PRIORITY
@ GNE_ATTR_STOPOEXCEPTION
stop exceptions (virtual, used by edge and lanes)
@ SUMO_ATTR_NUMLANES
@ GNE_ATTR_MODIFICATION_STATUS
whether a feature has been loaded,guessed,modified or approved
@ SUMO_ATTR_SHAPE
edge: the shape in xml-definition
@ SUMO_ATTR_DEPARTPOS
@ SUMO_ATTR_NAME
@ SUMO_ATTR_SPREADTYPE
The information about how to spread the lanes from the given position.
@ GNE_ATTR_IS_ROUNDABOUT
@ SUMO_ATTR_ENDOFFSET
@ GNE_ATTR_SHAPE_END
last coordinate of edge shape
@ SUMO_ATTR_TO
@ SUMO_ATTR_FROM
@ SUMO_ATTR_DISTANCE
@ GNE_ATTR_BIDIR
whether an edge is part of a bidirectional railway
@ SUMO_ATTR_TYPE
@ SUMO_ATTR_LENGTH
@ SUMO_ATTR_ID
@ GNE_ATTR_SHAPE_START
first coordinate of edge shape
@ SUMO_ATTR_WIDTH
@ SUMO_ATTR_FRICTION
@ SUMO_ATTR_ROUTINGTYPE
T MIN2(T a, T b)
Definition StdDefs.h:80
T MAX2(T a, T b)
Definition StdDefs.h:86
const double SUMO_const_halfLaneWidth
Definition StdDefs.h:53
std::string toString(const T &t, std::streamsize accuracy=gPrecision)
Definition ToString.h:49
A class that stores a 2D geometrical boundary.
Definition Boundary.h:39
void add(double x, double y, double z=0)
Makes the boundary include the given coordinate.
Definition Boundary.cpp:75
Boundary & grow(double by)
extends the boundary by the given amount
Definition Boundary.cpp:340
std::vector< std::string > consecutiveEdges
consecutive edges
static void setColor(const RGBColor &c)
Sets the gl-color to this value.
Definition GLHelper.cpp:649
static void popMatrix()
pop matrix
Definition GLHelper.cpp:131
static void drawBoundary(const GUIVisualizationSettings &s, const Boundary &b)
Draw a boundary (used for debugging)
Definition GLHelper.cpp:952
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 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 drawTextSettings(const GUIVisualizationTextSettings &settings, const std::string &text, const Position &pos, const double scale, const double angle=0, const double layer=2048, const int align=0)
Definition GLHelper.cpp:773
bool isAttributeCarrierSelected() const
check if attribute carrier is selected
double getCommonAttributeDouble(SumoXMLAttr key) const
bool myDrawInFront
boolean to check if drawn this AC over other elements
bool mySelected
boolean to check if this AC is selected (more quickly as checking GUIGlObjectStorage)
static const std::string FALSE_STR
true value in string format(used for comparing boolean values in getAttribute(...))
static const std::string TRUE_STR
true value in string format (used for comparing boolean values in getAttribute(......
const std::string getID() const override
get ID (all Attribute Carriers have one)
PositionVector getCommonAttributePositionVector(SumoXMLAttr key) const
void unselectAttributeCarrier()
unselect attribute carrier using GUIGlobalSelection
void setCommonAttribute(SumoXMLAttr key, const std::string &value, GNEUndoList *undoList)
const std::string & getTagStr() const
get tag assigned to this object in string format
static const std::string FEATURE_GUESSED
feature has been reguessed (may still be unchanged be we can't tell (yet)
bool drawUsingSelectColor() const
check if attribute carrier must be drawn using selecting color.
void drawInLayer(const double typeOrLayer, const double extraOffset=0) const
draw element in the given layer, or in front if corresponding flag is enabled
Position getCommonAttributePosition(SumoXMLAttr key) const
const GNETagProperties * getTagProperty() const
get tagProperty associated with this Attribute Carrier
GNENet * myNet
pointer to net
bool isCommonAttributeValid(SumoXMLAttr key, const std::string &value) const
std::string getCommonAttribute(SumoXMLAttr key) const
const GNETagProperties * myTagProperty
reference to tagProperty associated with this attribute carrier
static void changeAttribute(GNEAttributeCarrier *AC, SumoXMLAttr key, const std::string &value, GNEUndoList *undoList, const bool force=false)
change attribute
void updateGeometry() override
update pre-computed geometry information
void markConnectionGeometryDeprecated()
check that connection's Geometry has to be updated
void updateLinkState()
recompute cached myLinkState
void drawDottedContourGeometryPoints(const GUIVisualizationSettings &s, const GUIVisualizationSettings::Detail d, const GNEAttributeCarrier *AC, const PositionVector &shape, const double radius, const double scale, const double lineWidth) const
draw dotted contour for geometry points
void calculateContourEdgeGeometryPoints(const GUIVisualizationSettings &s, const GUIVisualizationSettings::Detail d, const GNEEdge *edge, const double radius, const bool calculatePosOverShape, const bool firstExtrem, const bool lastExtrem) const
calculate contour for edge geometry points
void calculateContourEdge(const GUIVisualizationSettings &s, const GUIVisualizationSettings::Detail d, const GNEEdge *edge, const GUIGlObject *elementToRegister, const double layer, const bool closeFirstExtrem, const bool closeLastExtrem) const
calculate contour edge
void calculateContourFirstGeometryPoint(const GUIVisualizationSettings &s, const GUIVisualizationSettings::Detail d, const GUIGlObject *glObject, const PositionVector &shape, const double layer, const double radius, const double scale, const bool forceCalculation=false) const
calculate contour for first geometry point
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...)
bool deleteOnlyGeometryPoints() const
check if only delete geometry points checkbox is enabled
struct for saving subordinated elements (Junction->Edge->Lane->(Additional | DemandElement)
ProtectElements * getProtectElements() const
get protect elements modul
DeleteOptions * getDeleteOptions() const
get delete options modul
void updateDemandElementStackLabel(const int stack)
update stack label
Stack demand elements.
Definition GNEEdge.h:409
const StackPosition & getStackPosition() const
get stack position
Definition GNEEdge.cpp:1812
const std::vector< GNEDemandElement * > & getDemandElements() const
get demand elements
Definition GNEEdge.cpp:1818
void addDemandElements(GNEDemandElement *demandElement)
add demand elment to current StackDemandElements
Definition GNEEdge.cpp:1806
StackDemandElements(const StackPosition stackedPosition, GNEDemandElement *demandElement)
constructor
Definition GNEEdge.cpp:1798
Stack position (used to stack demand elements over edges)
Definition GNEEdge.h:395
double beginPosition() const
get begin position
Definition GNEEdge.cpp:1787
StackPosition(const double departPos, const double length)
constructor
Definition GNEEdge.cpp:1781
double endPosition() const
get end position
Definition GNEEdge.cpp:1793
void drawEdgeGeometryPoints(const GUIVisualizationSettings &s, const GUIVisualizationSettings::Detail d, const double layer) const
draw edge geometry points (note: This function is called by GNELane::drawGL(...)
Definition GNEEdge.cpp:2521
double getAttributeDouble(SumoXMLAttr key) const override
Definition GNEEdge.cpp:1197
const Position getFrontDownShapePosition() const
get front down shape position
Definition GNEEdge.cpp:896
Boundary myEdgeBoundary
edge boundary
Definition GNEEdge.h:429
void updateCenteringBoundary(const bool updateGrid)
update centering boundary (implies change in RTREE)
Definition GNEEdge.cpp:634
void drawEdgeName(const GUIVisualizationSettings &s) const
draw edge name
Definition GNEEdge.cpp:2699
bool isConvexAngle() const
check if edge makes a convex angle [0 - 180) degrees
Definition GNEEdge.cpp:1731
void setNumLanes(int numLanes, GNEUndoList *undoList)
changes the number of lanes. When reducing the number of lanes, higher-numbered lanes are removed fir...
Definition GNEEdge.cpp:1989
bool isNetworkElementValid() const override
check if current network element is valid to be written into XML
Definition GNEEdge.cpp:152
std::string getAttributeForSelection(SumoXMLAttr key) const override
method for getting the attribute in the context of object selection
Definition GNEEdge.cpp:1220
const std::map< const GNELane *, std::vector< GNEDemandElement * > > getPersonsOverEdgeMap() const
get persons a that start over this edge
Definition GNEEdge.cpp:2456
PositionVector getAttributePositionVector(SumoXMLAttr key) const override
Definition GNEEdge.cpp:1209
const std::map< const GNELane *, std::vector< GNEDemandElement * > > getContainersOverEdgeMap() const
get containers a that start over this edge
Definition GNEEdge.cpp:2489
bool hasPredecessors() const
check if this edge has predecessors (note: only for vehicles, this function ignore walking areas!...
Definition GNEEdge.cpp:1746
friend class GNEChange_Lane
Friend class.
Definition GNEEdge.h:54
void updateGLObject() override
update GLObject (geometry, ID, etc.)
Definition GNEEdge.cpp:749
~GNEEdge()
Destructor.
Definition GNEEdge.cpp:104
void smooth(GNEUndoList *undoList)
make geometry smooth
Definition GNEEdge.cpp:2350
void setAttribute(SumoXMLAttr key, const std::string &value, GNEUndoList *undoList) override
Definition GNEEdge.cpp:1230
double getGeometryPointRadius() const
get geometry point radius
Definition GNEEdge.cpp:2957
void setResponsible(bool newVal)
set responsibility for deleting internal structures
Definition GNEEdge.cpp:1502
void copyEdgeType(const GNEEdgeType *edgeType, GNEUndoList *undoList)
copy edge attributes from edgeType
Definition GNEEdge.cpp:1047
NBEdge * getNBEdge() const
returns the internal NBEdge
Definition GNEEdge.cpp:755
GUIGLObjectPopupMenu * getPopUpMenu(GUIMainWindow &app, GUISUMOAbstractView &parent) override
Returns an own popup-menu.
Definition GNEEdge.cpp:681
const std::map< const GNELane *, std::vector< GNEDemandElement * > > getVehiclesOverEdgeMap() const
get vehicles a that start over this edge
Definition GNEEdge.cpp:2414
std::set< GUIGlID > getLaneGlIDs() const
returns GLIDs of all lanes
Definition GNEEdge.cpp:1079
GNEEdge * getReverseEdge() const
get reverse edge (if exist)
Definition GNEEdge.cpp:1768
const Position getFrontUpShapePosition() const
get front up shape position
Definition GNEEdge.cpp:888
void setGeometry(PositionVector geom, bool inner)
update edge geometry and inform the lanes
Definition GNEEdge.cpp:853
void smoothElevation(GNEUndoList *undoList)
smooth elevation with regard to adjoining edges
Definition GNEEdge.cpp:2362
bool clickedOverGeometryPoint(const Position &pos) const
return true if user clicked over a Geometry Point
Definition GNEEdge.cpp:587
bool clickedOverShapeEnd(const Position &pos) const
return true if user clicked over ShapeEnd
Definition GNEEdge.cpp:575
void updateVehicleStackLabels()
Definition GNEEdge.cpp:1569
void remakeGNEConnections(bool junctionsReady=false)
remake connections
Definition GNEEdge.cpp:919
bool isAttributeComputed(SumoXMLAttr key) const override
Definition GNEEdge.cpp:1485
void calculateEdgeContour(const GUIVisualizationSettings &s, const GUIVisualizationSettings::Detail d, const double layer) const
calculate contours
Definition GNEEdge.cpp:2809
static const double SNAP_RADIUS
Definition GNEEdge.h:318
GNELane * getLaneByAllowedVClass(const SUMOVehicleClass vClass) const
return the first lane that allow a vehicle of type vClass (or the first lane, if none was found)
Definition GNEEdge.cpp:1508
bool hasCustomEndPoints() const
Definition GNEEdge.cpp:551
void updatePersonStackLabels()
Definition GNEEdge.cpp:1627
void setEdgeID(const std::string &newID)
set edge ID
Definition GNEEdge.cpp:2236
void removeConnection(NBEdge::Connection nbCon)
removes a connection
Definition GNEEdge.cpp:2181
void drawChildrens(const GUIVisualizationSettings &s) const
draw children
Definition GNEEdge.cpp:2781
bool hasSuccessors() const
check if this edge has successors (note: only for vehicles, this function ignore walking areas!...
Definition GNEEdge.cpp:1762
void drawStartGeometryPoint(const GUIVisualizationSettings &s, const GUIVisualizationSettings::Detail d, const double geometryPointRadius, const double layer, const double exaggeration) const
draw start extreme geometry point
Definition GNEEdge.cpp:2571
GNEMoveElementEdge * myMoveElementEdge
move element edge
Definition GNEEdge.h:426
bool drawBigGeometryPoints() const
check if draw big geometry points
Definition GNEEdge.cpp:2923
bool myWasSplit
whether this edge was created from a split
Definition GNEEdge.h:388
void removeLane(GNELane *lane, bool recomputeConnections)
@briefdecrease the number of lanes by one. argument is only used to increase robustness (assertions)
Definition GNEEdge.cpp:2105
GNEMoveElement * getMoveElement() const override
methods to retrieve the elements linked to this edge
Definition GNEEdge.cpp:134
bool hasRestrictedLane(SUMOVehicleClass vclass) const
check if edge has a restricted lane
Definition GNEEdge.cpp:2245
static const double SNAP_RADIUS_SQUARED
Definition GNEEdge.h:321
void updateSecondParentJunction(const std::string &value)
update last parent junction
Definition GNEEdge.cpp:2038
const std::string getOptionalName() const override
Returns the street name.
Definition GNEEdge.cpp:675
std::vector< GNEEdge * > getOppositeEdges() const
get opposite edges
Definition GNEEdge.cpp:689
PositionVector smoothShape(const PositionVector &shape, bool forElevation)
return smoothed shape
Definition GNEEdge.cpp:2277
bool checkDrawSelectContour() const override
check if draw select contour (blue)
Definition GNEEdge.cpp:476
GNEJunction * getFromJunction() const
get from Junction (only used to increase readability)
Definition GNEEdge.h:87
bool wasSplit()
whether this edge was created from a split
Definition GNEEdge.cpp:1095
NBEdge * myNBEdge
the underlying NBEdge
Definition GNEEdge.h:376
void copyTemplate(const GNEEdgeTemplate *edgeTemplate, GNEUndoList *undoList)
copy edge attributes from edgetemplate
Definition GNEEdge.cpp:1024
void removeEdgeFromCrossings(GNEJunction *junction, GNEUndoList *undoList)
remove crossing of junction
Definition GNEEdge.cpp:2256
bool checkDrawMoveContour() const override
check if draw move contour (red)
Definition GNEEdge.cpp:507
Position getPositionInView() const
Returns position of hierarchical element in view.
Definition GNEEdge.cpp:216
void addLane(GNELane *lane, const NBEdge::Lane &laneAttrs, bool recomputeConnections)
increase number of lanes by one use the given attributes and restore the GNELane
Definition GNEEdge.cpp:2045
GNEConnection * retrieveGNEConnection(int fromLane, NBEdge *to, int toLane, bool createIfNoExist=true)
get GNEConnection if exist, and if not create it if create is enabled
Definition GNEEdge.cpp:2215
Position getAttributePosition(SumoXMLAttr key) const override
Definition GNEEdge.cpp:1203
bool checkDrawToContour() const override
check if draw from contour (magenta)
Definition GNEEdge.cpp:280
ConnectionVector myGNEConnections
vector with the connections of this edge
Definition GNEEdge.h:379
void editEndpoint(Position pos, GNEUndoList *undoList)
makes pos the new geometry endpoint at the appropriate end, or remove current existent endpoint
Definition GNEEdge.cpp:777
void resetBothEndpoint(GNEUndoList *undoList)
restores both endpoint to the junction position at the appropriate end
Definition GNEEdge.cpp:843
Position getSplitPos(const Position &clickPos)
Definition GNEEdge.cpp:761
void drawGL(const GUIVisualizationSettings &s) const override
Draws the object.
Definition GNEEdge.cpp:695
const std::vector< GNEConnection * > & getGNEConnections() const
returns a reference to the GNEConnection vector
Definition GNEEdge.cpp:1089
bool isValid(SumoXMLAttr key, const std::string &value) override
Definition GNEEdge.cpp:1368
int getRouteProbeRelativePosition(GNERouteProbe *routeProbe) const
obtain relative positions of RouteProbes
Definition GNEEdge.cpp:989
bool checkDrawRelatedContour() const override
check if draw related contour (cyan)
Definition GNEEdge.cpp:338
std::string myConnectionStatus
modification status of the connections
Definition GNEEdge.h:391
void drawEndGeometryPoint(const GUIVisualizationSettings &s, const GUIVisualizationSettings::Detail d, const double geometryPointRadius, const double layer, const double exaggeration) const
draw end extreme geometry point
Definition GNEEdge.cpp:2635
double getExaggeration(const GUIVisualizationSettings &s) const override
return exaggeration associated with this GLObject
Definition GNEEdge.cpp:622
bool checkDrawDeleteContour() const override
check if draw delete contour (pink/white)
Definition GNEEdge.cpp:430
Boundary getCenteringBoundary() const override
Returns the boundary to which the view shall be centered in order to show the object.
Definition GNEEdge.cpp:628
void clearGNEConnections()
clear current connections
Definition GNEEdge.cpp:964
bool myUpdateGeometry
flag to enable/disable update geometry of lanes (used mainly by setNumLanes)
Definition GNEEdge.h:432
const Position getBackDownShapePosition() const
get back down shape position
Definition GNEEdge.cpp:912
bool areStackPositionOverlapped(const GNEEdge::StackPosition &vehicleA, const GNEEdge::StackPosition &vehicleB) const
check if given stacked positions are overlapped
Definition GNEEdge.cpp:2941
bool checkDrawDeleteContourSmall() const override
check if draw delete contour small (pink/white)
Definition GNEEdge.cpp:461
void updateFirstParentJunction(const std::string &value)
update front parent junction
Definition GNEEdge.cpp:2031
void updateGeometry() override
update pre-computed geometry information
Definition GNEEdge.cpp:170
void straightenElevation(GNEUndoList *undoList)
interpolate z values linear between junctions
Definition GNEEdge.cpp:2267
void updateContainerStackLabels()
Definition GNEEdge.cpp:1679
bool clickedOverShapeStart(const Position &pos) const
return true if user clicked over ShapeStart
Definition GNEEdge.cpp:563
void deleteGLObject() override
delete element
Definition GNEEdge.cpp:740
void setShapeStartPos(const Position &pos)
change Shape StartPos
Definition GNEEdge.cpp:2392
GNEJunction * getToJunction() const
get from Junction (only used to increase readability)
Definition GNEEdge.h:92
const Position getBackUpShapePosition() const
get back up shape position
Definition GNEEdge.cpp:904
void resetEndpoint(const Position &pos, GNEUndoList *undoList)
restores the endpoint to the junction position at the appropriate end
Definition GNEEdge.cpp:829
bool isAttributeEnabled(SumoXMLAttr key) const override
Definition GNEEdge.cpp:1470
void addConnection(NBEdge::Connection nbCon, bool selectAfterCreation=false)
adds a connection
Definition GNEEdge.cpp:2157
void drawLaneStopOffset(const GUIVisualizationSettings &s, const GUIVisualizationSettings::Detail d, const double layer) const
draw edgeStopOffset
Definition GNEEdge.cpp:2762
void drawTAZElements(const GUIVisualizationSettings &s) const
draw TAZElements
Definition GNEEdge.cpp:2832
void drawEdgeShape(const GUIVisualizationSettings &s, const GUIVisualizationSettings::Detail d, const double layer) const
draw edge shape (only one line)
Definition GNEEdge.cpp:2885
std::vector< GNECrossing * > getGNECrossings()
get GNECrossings vinculated with this Edge
Definition GNEEdge.cpp:1007
bool checkDrawFromContour() const override
check if draw from contour (green)
Definition GNEEdge.cpp:222
GNELane * getLaneByDisallowedVClass(const SUMOVehicleClass vClass) const
return the first lane that disallow a vehicle of type vClass (or the first lane, if none was found)
Definition GNEEdge.cpp:1523
Parameterised * getParameters() override
get parameters associated with this edge
Definition GNEEdge.cpp:140
void updateVehicleSpreadGeometries()
Definition GNEEdge.cpp:1538
bool checkDrawOverContour() const override
check if draw over contour (orange)
Definition GNEEdge.cpp:358
std::string getAttribute(SumoXMLAttr key) const override
Definition GNEEdge.cpp:1101
void updateJunctionPosition(GNEJunction *junction, const Position &origPos)
update edge geometry after junction move
Definition GNEEdge.cpp:608
bool myAmResponsible
whether we are responsible for deleting myNBNode
Definition GNEEdge.h:385
GNEEdge(GNENet *net, NBEdge *nbe, bool wasSplit=false, bool loaded=false)
Constructor.
Definition GNEEdge.cpp:76
void setShapeEndPos(const Position &pos)
change Shape EndPos
Definition GNEEdge.cpp:2403
std::string getNetworkElementProblem() const override
return a string with the current network element problem
Definition GNEEdge.cpp:162
const std::vector< GNELaneTemplate * > & getLaneTemplates() const
get vector with the lane templates of this edge
std::string getAttribute(SumoXMLAttr key) const override
std::string getAttribute(SumoXMLAttr key) const override
const std::vector< GNELaneType * > & getLaneTypes() const
get laneTypes
void removeCurrentEditedAttributeCarrier(const GNEAttributeCarrier *HE)
if given AttributeCarrier is the same of myHE, set it as nullptr
const GNEHierarchicalContainerChildren< GNEEdge * > & getChildEdges() const
get child edges
const GNEHierarchicalContainerChildren< GNEGenericData * > & getChildGenericDatas() const
return child generic data elements
const GNEHierarchicalContainerChildren< GNELane * > & getChildLanes() const
get child lanes
static void insertChild(ElementType element, ChildType child)
insert child element
const GNEHierarchicalContainerChildren< GNEAdditional * > & getChildAdditionals() const
return child additionals
const GNEHierarchicalContainerChildrenSet< GNETAZSourceSink * > & getChildTAZSourceSinks() const
return child TAZSourceSinks (Set)
void addChildElement(ChildType *element)
add child without updating parent (ONLY used if we're creating elements without undo-redo)
const GNEHierarchicalContainerParents< GNEJunction * > & getParentJunctions() const
get parent junctions
static void removeChild(ElementType element, ChildType child)
remove child element
static void updateParent(ElementType element, const int index, ParentType newParent)
update single parent element
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)
void updateEdgeTemplate()
update edge template
TemplateEditor * getTemplateEditor() const
get template editor
GNEElementTree * getHierarchicalElementTree() const
get GNEElementTree modul
const std::vector< GNEEdge * > & getGNEIncomingEdges() const
Returns incoming GNEEdges.
const std::vector< GNECrossing * > & getGNECrossings() const
Returns GNECrossings.
void invalidateShape()
void updateGeometry() override
update pre-computed geometry information (including crossings)
Boundary getCenteringBoundary() const override
Returns the boundary to which the view shall be centered in order to show the object.
void removeOutgoingGNEEdge(GNEEdge *edge)
remove outgoing GNEEdge
void removeIncomingGNEEdge(GNEEdge *edge)
remove incoming GNEEdge
void drawGL(const GUIVisualizationSettings &s) const override
Draws the object.
void addIncomingGNEEdge(GNEEdge *edge)
add incoming GNEEdge
const std::vector< GNEEdge * > & getGNEOutgoingEdges() const
Returns incoming GNEEdges.
NBNode * getNBNode() const
Return net build node.
void setLogicValid(bool valid, GNEUndoList *undoList, const std::string &status=FEATURE_GUESSED)
void addOutgoingGNEEdge(GNEEdge *edge)
add outgoing GNEEdge
const PositionVector & getLaneShape() const
get elements shape
Definition GNELane.cpp:232
double getColorValue(const GUIVisualizationSettings &s, int activeScheme) const override
return value for lane coloring according to the given scheme
Definition GNELane.cpp:1557
int getIndex() const
returns the index of the lane
Definition GNELane.cpp:624
void setIndex(int index)
Definition GNELane.cpp:630
void removeGeometryPoint(const Position clickedPosition, GNEUndoList *undoList) override
remove geometry point in the clicked position
bool getForceDrawGeometryPoints() const
check if option "force draw geometry points" is enabled
NetworkMoveOptions * getNetworkMoveOptions() const
get network mode options
std::vector< GNEEdge * > retrieveEdges(GNEJunction *from, GNEJunction *to) const
get all edges by from and to GNEJunction
const std::unordered_map< const GUIGlObject *, GNEConnection * > & getConnections() const
get connections
void insertLane(GNELane *lane)
insert lane in container
void deleteConnection(GNEConnection *connection)
delete connection from container
GNEJunction * retrieveJunction(const std::string &id, bool hardFail=true) const
get junction by id
void insertConnection(GNEConnection *connection)
insert connection in container
void updateEdgeID(GNEEdge *edge, const std::string &newID)
update edge ID in container
GNEEdge * retrieveEdge(const std::string &id, bool hardFail=true) const
get edge by id
const std::unordered_map< const GUIGlObject *, GNELane * > & getLanes() const
get lanes
void deleteLane(GNELane *lane)
delete lane from container
void requireSaveDemandElements()
inform that demand elements has to be saved
void deleteEdge(GNEEdge *edge, GNEUndoList *undoList, bool recomputeConnections)
removes edge
Definition GNENet.cpp:485
void deleteLane(GNELane *lane, GNEUndoList *undoList, bool recomputeConnections)
removes lane
Definition GNENet.cpp:664
void deleteCrossing(GNECrossing *crossing, GNEUndoList *undoList)
remove crossing
Definition GNENet.cpp:721
void addGLObjectIntoGrid(GNEAttributeCarrier *AC)
add GL Object into net
Definition GNENet.cpp:1447
void removeGLObjectFromGrid(GNEAttributeCarrier *AC)
add GL Object into net
Definition GNENet.cpp:1457
GNENetHelper::SavingStatus * getSavingStatus() const
get saving status
Definition GNENet.cpp:186
GNEPathManager * getDemandPathManager()
get demand path manager
Definition GNENet.cpp:198
void removeExplicitTurnaround(std::string id)
remove edge id from the list of explicit turnarounds
Definition GNENet.cpp:2218
GNENetHelper::AttributeCarriers * getAttributeCarriers() const
get all attribute carriers used in this net
Definition GNENet.cpp:174
void changeEdgeEndpoints(GNEEdge *edge, const std::string &newSourceID, const std::string &newDestID)
modifies endpoins of the given edge
Definition GNENet.cpp:2191
const GNETagPropertiesDatabase * getTagPropertiesDatabase() const
get tag properties database (used for simplify code)
Definition GNENet.cpp:162
GNEViewParent * getViewParent() const
get view parent (used for simplify code)
Definition GNENet.cpp:150
GNEUndoList * getUndoList() const
get undo list(used for simplify code)
Definition GNENet.cpp:156
GNEViewNet * getViewNet() const
get view net (used for simplify code)
Definition GNENet.cpp:144
bool checkDrawingBoundarySelection() const
GNEContour myNetworkElementContour
network element contour
GNEHierarchicalElement * getHierarchicalElement() override
methods to retrieve the elements linked to this network element
void setNetworkElementID(const std::string &newID)
set network element id
void invalidatePathCalculator()
invalidate pathCalculator
PathCalculator * getPathCalculator()
obtain instance of PathCalculator
const CommonXMLStructure::PlanParameters & getPlanParameteres() const
get plan parameters
bool markEdges() const
check if mark edges with dotted contours
void decRef(const std::string &debugMsg="")
Decrease reference.
void incRef(const std::string &debugMsg="")
Increase reference.
bool unreferenced()
check if object ins't referenced
const GNETagProperties * getTagProperty(const SumoXMLTag tag, const bool hardFail) const
get tagProperty associated to the given tag
SumoXMLTag getTag() const
get Tag vinculated with this attribute Property
const std::vector< const GNEAttributeProperties * > & getAttributeProperties() const
get all attribute properties
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...
void add(GNEChange *command, bool doit=false, bool merge=true)
Add new command, executing it if desired. The new command will be merged with the previous command if...
void uninspectAC(GNEAttributeCarrier *AC)
uninspect AC
GNEEdge * getEdgeFront() const
get front edge or a pointer to nullptr
GNEAttributeCarrier * getAttributeCarrierFront() const
get front attribute carrier or a pointer to nullptr
const GUIGlObject * getGUIGlObjectFront() const
get front GUIGLObject or a pointer to nullptr
GNEJunction * getJunctionFront() const
get front junction or a pointer to nullptr
bool isCurrentlyMovingElements() const
check if an element is being moved
const GNEViewNetHelper::DataViewOptions & getDataViewOptions() const
get data view options
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::MoveSingleElementModul & getMoveSingleElementValues() const
get move single element values
const GNEViewNetHelper::NetworkViewOptions & getNetworkViewOptions() const
get network view options
bool checkOverLockedElement(const GUIGlObject *GLObject, const bool isSelected) const
check if given element is locked (used for drawing select and delete contour)
bool checkSelectEdges() const
check if select edges (toggle using button or shift)
const GNEViewNetHelper::ViewObjectsSelector & getViewObjectsSelector() const
get objects under cursor
GNEMoveFrame * getMoveFrame() const
get frame for move elements
GNEDeleteFrame * getDeleteFrame() const
get frame for delete elements
GNEInspectorFrame * getInspectorFrame() const
get frame for inspect elements
The popup menu of a globject.
GUIGlObject * getGLObject() const
The object that belongs to this popup-menu.
static void drawGeometry(const GUIVisualizationSettings::Detail d, const GUIGeometry &geometry, const double width, double offset=0)
draw geometry
const std::string & getMicrosimID() const
Returns the id of the object as known to microsim.
GUIGlObjectType getType() const
Returns the type of the object as coded in GUIGlObjectType.
void drawName(const Position &pos, const double scale, const GUIVisualizationTextSettings &settings, const double angle=0, bool forceShow=false) const
draw name of item
T getColor(const double value) const
const std::vector< T > & getSchemes() const
Position snapToActiveGrid(const Position &pos, bool snapXY=true) const
Returns a position that is mapped to the closest grid point if the grid is active.
const GUIVisualizationSettings & getVisualisationSettings() const
get visualization settings (read only)
GUIGLObjectPopupMenu * getPopup() const
ge the current popup-menu
const Triangle & getSelectionTriangle() const
get selection triangle
const std::vector< int > & getSelectedGeometryPoints(const GUIGlObject *GLObject) const
get geometry points for the given glObject
bool selectingUsingRectangle() const
return true if we're selecting using a triangle
const GUIGlObject * markedFirstGeometryPoint
marked first geometry point (used for moving/delete geometry points)
bool selectObject(const GUIGlObject *GLObject, const double layer, const bool checkDuplicated, const GNESegment *segment)
Stores the information about how to visualize structures.
GUIVisualizationSizeSettings addSize
GUIVisualizationTextSettings edgeValue
double laneWidthExaggeration
The lane exaggeration (upscale thickness)
GUIVisualizationColorSettings colorSettings
color settings
GUIVisualizationDottedContourSettings dottedContourSettings
dotted contour settings
double scale
information about a lane's width (temporary, used for a single view)
GUIVisualizationTextSettings streetName
bool drawForViewObjectsHandler
whether drawing is performed for the purpose of selecting objects in view using ViewObjectsHandler
GUIColorer laneColorer
The lane colorer.
GUIVisualizationTextSettings edgeName
Setting bundles for optional drawing names with size and color.
bool checkDrawEdge(const Boundary &b) const
check if draw edge
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 const double INVALID_OFFSET
a value to signify offsets outside the range of [0, Line.length()]
Definition GeomHelper.h:50
The representation of a single edge during network building.
Definition NBEdge.h:92
void setStreetName(const std::string &name)
sets the street name of this edge
Definition NBEdge.h:680
void mirrorX()
mirror coordinates along the x-axis
Definition NBEdge.cpp:593
void setPreferredVehicleClass(SVCPermissions permissions, int lane=-1)
set preferred Vehicle Class
Definition NBEdge.cpp:4517
SVCPermissions getPermissions(int lane=-1) const
get the union of allowed classes over all lanes or for a specific lane
Definition NBEdge.cpp:4540
const std::vector< Connection > & getConnections() const
Returns the connections.
Definition NBEdge.h:1047
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:4503
StopOffset myEdgeStopOffset
A vClass specific stop offset - assumed of length 0 (unspecified) or 1. For the latter case the int i...
Definition NBEdge.h:1823
double getLoadedLength() const
Returns the length was set explicitly or the computed length if it wasn't set.
Definition NBEdge.h:608
void setSpeed(int lane, double speed)
set lane specific speed (negative lane implies set for all lanes)
Definition NBEdge.cpp:4455
bool hasLaneSpecificFriction() const
whether lanes differ in friction
Definition NBEdge.cpp:2485
double getLaneWidth() const
Returns the default width of lanes of this edge.
Definition NBEdge.h:648
NBNode * getToNode() const
Returns the destination node of the edge.
Definition NBEdge.h:552
Lane & getLaneStruct(int lane)
Definition NBEdge.h:1451
void addLane(int index, bool recomputeShape, bool recomputeConnections, bool shiftIndices)
add lane
Definition NBEdge.cpp:4192
bool hasLaneSpecificSpeed() const
whether lanes differ in speed
Definition NBEdge.cpp:2475
std::string myType
The type of the edge.
Definition NBEdge.h:1760
const PositionVector & getGeometry() const
Returns the geometry of the edge.
Definition NBEdge.h:789
LaneSpreadFunction getLaneSpreadFunction() const
Returns how this edge's lanes' lateral offset is computed.
Definition NBEdge.cpp:1021
bool hasLoadedLength() const
Returns whether a length was set explicitly.
Definition NBEdge.h:618
void setDistance(double distance)
set kilometrage at start of edge (negative value implies couting down along the edge)
Definition NBEdge.h:1425
const std::string & getRoutingType() const
return whether this edge should be a bidi edge
Definition NBEdge.h:1446
const std::vector< NBEdge::Lane > & getLanes() const
Returns the lane definitions.
Definition NBEdge.h:736
double getSpeed() const
Returns the speed allowed on this edge.
Definition NBEdge.h:625
const std::string & getID() const
Definition NBEdge.h:1551
double getDistance() const
get distance
Definition NBEdge.h:685
static const double UNSPECIFIED_LOADED_LENGTH
no length override given
Definition NBEdge.h:364
void setLaneWidth(int lane, double width)
set lane specific width (negative lane implies set for all lanes)
Definition NBEdge.cpp:4326
void setLaneSpreadFunction(LaneSpreadFunction spread)
(Re)sets how the lanes lateral offset shall be computed
Definition NBEdge.cpp:1015
bool isTurningDirectionAt(const NBEdge *const edge) const
Returns whether the given edge is the opposite direction to this edge.
Definition NBEdge.cpp:3807
bool hasLaneSpecificPermissions() const
whether lanes differ in allowed vehicle classes
Definition NBEdge.cpp:2461
bool isBidiEdge(bool checkPotential=false) const
whether this edge is part of a bidirectional edge pair
Definition NBEdge.cpp:784
void setBidi(bool isBidi)
mark this edge as a bidi edge
Definition NBEdge.h:1430
int getNumLanes() const
Returns the number of lanes.
Definition NBEdge.h:526
void setFriction(int lane, double friction)
set lane specific friction (negative lane implies set for all lanes)
Definition NBEdge.cpp:4471
void removeFromConnections(NBEdge *toEdge, int fromLane=-1, int toLane=-1, bool tryLater=false, const bool adaptToLaneRemoval=false, const bool keepPossibleTurns=false)
Removes the specified connection(s)
Definition NBEdge.cpp:1471
void invalidateConnections(bool reallowSetting=false)
invalidate current connections of edge
Definition NBEdge.cpp:1552
void deleteLane(int index, bool recompute, bool shiftIndices)
delete lane
Definition NBEdge.cpp:4247
bool hasLaneSpecificWidth() const
whether lanes differ in width
Definition NBEdge.cpp:2495
std::string getLaneID(int lane) const
get lane ID
Definition NBEdge.cpp:4178
@ USER
The connection was given by the user.
double getFriction() const
Returns the friction on this edge.
Definition NBEdge.h:632
bool setConnection(int lane, NBEdge *destEdge, int destLane, Lane2LaneInfoType type, bool mayUseSameDestination=false, bool mayDefinitelyPass=false, KeepClear keepClear=KEEPCLEAR_UNSPECIFIED, double contPos=UNSPECIFIED_CONTPOS, double visibility=UNSPECIFIED_VISIBILITY_DISTANCE, double speed=UNSPECIFIED_SPEED, double friction=UNSPECIFIED_FRICTION, double length=myDefaultConnectionLength, const PositionVector &customShape=PositionVector::EMPTY, const bool uncontrolled=UNSPECIFIED_CONNECTION_UNCONTROLLED, SVCPermissions permissions=SVC_UNSPECIFIED, bool indirectLeft=false, const std::string &edgeType="", SVCPermissions changeLeft=SVC_UNSPECIFIED, SVCPermissions changeRight=SVC_UNSPECIFIED, bool postProcess=false)
Adds a connection to a certain lane of a certain edge.
Definition NBEdge.cpp:1209
bool hasLaneSpecificEndOffset() const
whether lanes differ in offset
Definition NBEdge.cpp:2517
const std::string & getTypeID() const
get ID of type
Definition NBEdge.h:1187
const std::string & getStreetName() const
Returns the street name of this edge.
Definition NBEdge.h:675
const NBEdge * getBidiEdge() const
Definition NBEdge.h:1537
NBNode * getFromNode() const
Returns the origin node of the edge.
Definition NBEdge.h:545
NBEdge * getTurnDestination(bool possibleDestination=false) const
Definition NBEdge.cpp:4169
std::string myRoutingType
The routing type of the edge.
Definition NBEdge.h:1865
int getPriority() const
Returns the priority of the edge.
Definition NBEdge.h:533
static const double UNSPECIFIED_WIDTH
unspecified lane width
Definition NBEdge.h:346
void declareConnectionsAsLoaded(EdgeBuildingStep step=EdgeBuildingStep::LANES2LANES_USER)
declares connections as fully loaded. This is needed to avoid recomputing connections if an edge has ...
Definition NBEdge.h:1465
double getEndOffset() const
Returns the offset to the destination node.
Definition NBEdge.h:695
void setEndOffset(int lane, double offset)
set lane specific end-offset (negative lane implies set for all lanes)
Definition NBEdge.cpp:4409
void setLoadedLength(double val)
set loaded length
Definition NBEdge.cpp:4555
const PositionVector getInnerGeometry() const
Returns the geometry of the edge without the endpoints.
Definition NBEdge.cpp:613
double getFinalLength() const
get length that will be assigned to the lanes in the final network
Definition NBEdge.cpp:4891
void setGeometry(const PositionVector &g, bool inner=false)
(Re)sets the edge's geometry
Definition NBEdge.cpp:660
int myPriority
The priority of the edge.
Definition NBEdge.h:1779
const EdgeVector & getIncomingEdges() const
Returns this node's incoming edges (The edges which yield in this node)
Definition NBNode.h:268
const EdgeVector & getOutgoingEdges() const
Returns this node's outgoing edges (The edges which start at this node)
Definition NBNode.h:273
const Position & getPosition() const
Definition NBNode.h:260
bool isRoundabout() const
return whether this node is part of a roundabout
Definition NBNode.cpp:4073
bool geometryLike() const
whether this is structurally similar to a geometry node
Definition NBNode.cpp:4027
static PositionVector bezierControlPoints(const PositionVector &begShape, const PositionVector &endShape, bool isTurnaround, double extrapolateBeg, double extrapolateEnd, bool &ok, NBNode *recordError=0, double straightThresh=DEG2RAD(5), int shapeFlag=0)
get bezier control points
Definition NBNode.cpp:618
const std::string & getID() const
Returns the id.
Definition Named.h:74
bool set(const std::string &name, const std::string &value, const bool append=false)
Sets the given value for the named option.
bool getBool(const std::string &name) const
Returns the boolean-value of the named option (only for Option_Bool)
void resetWritable()
Resets all options to be writeable.
static OptionsCont & getOptions()
Retrieves the options.
An upper class for objects with additional parameters.
virtual const std::string getParameter(const std::string &key, const std::string defaultValue="") const
Returns the value for a given key.
A point in 2D or 3D with translation and scaling methods.
Definition Position.h:37
double distanceTo2D(const Position &p2) const
returns the euclidean distance in the x-y-plane
Definition Position.h:273
void add(const Position &pos)
Adds the given position to this one.
Definition Position.h:129
void mul(double val)
Multiplies position with the given value.
Definition Position.h:102
double z() const
Returns the z-position.
Definition Position.h:62
A list of positions.
double length2D() const
Returns the length.
double length() const
Returns the length.
double rotationAtOffset(double pos) const
Returns the rotation at the given length.
PositionVector resample(double maxLength, const bool adjustEnd) const
resample shape (i.e. transform to segments, equal spacing)
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.
void add(double xoff, double yoff, double zoff)
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
void move2side(double amount, double maxExtension=100)
move position vector to side using certain amount
PositionVector interpolateZ(double zStart, double zEnd) const
returned vector that varies z smoothly over its length
Boundary getBoxBoundary() const
Returns a boundary enclosing this list of lines.
static const PositionVector EMPTY
empty Vector
PositionVector bezier(int numPoints)
return a bezier interpolation
void push_front(const Position &p)
insert in front a Position
Position positionAtOffset2D(double pos, double lateralOffset=0, bool extrapolateBeyond=false) const
Returns the position at the given length.
void pop_front()
pop first Position
PositionVector reverse() const
reverse position vector
static const RGBColor BLUE
Definition RGBColor.h:190
unsigned char alpha() const
Returns the alpha-amount of the color.
Definition RGBColor.cpp:92
static const RGBColor ORANGE
Definition RGBColor.h:194
static const RGBColor CYAN
Definition RGBColor.h:192
RGBColor changedBrightness(int change, int toChange=3) const
Returns a new color with altered brightness.
Definition RGBColor.cpp:200
static StringBijection< LaneSpreadFunction > LaneSpreadFunctions
lane spread functions
static bool isValidNetID(const std::string &value)
whether the given string is a valid id for a network element
void setOffset(const double offset)
set offset
bool isDefined() const
check if stopOffset was defined
SVCPermissions getPermissions() const
get permissions
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
const std::string & getString(const T key) const
get string
bool hasString(const std::string &str) const
check if the given string exist
bool isBoundaryFullWithin(const Boundary &boundary) const
check if the given position is FULL within this triangle
Definition Triangle.cpp:60
bool showDemandElements() const
check if show demand elements checkbox is enabled
NetworkEditMode networkEditMode
the current Network edit mode
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
GNEMoveElement * getMovedElement() const
get moved element
bool editingElevation() const
check if we're editing elevation
bool showDemandElements() const
check if show demand elements checkbox is enabled
bool showTAZElements() const
check if show TAZ Elements
RGBColor selectedEdgeColor
edge selection color
static const double segmentWidthSmall
width of small dotted contour segments
static const double segmentWidth
width of dotted contour segments
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 scaledSize(double scale, double constFactor=0.1) const
get scale size
A structure which describes a connection between edges or lanes.
Definition NBEdge.h:201
int fromLane
The lane the connections starts at.
Definition NBEdge.h:210
int toLane
The lane the connections yields in.
Definition NBEdge.h:216
double speed
custom speed for connection
Definition NBEdge.h:240
NBEdge * toEdge
The edge the connections yields in.
Definition NBEdge.h:213
KeepClear keepClear
whether the junction must be kept clear when using this connection
Definition NBEdge.h:231
double customLength
custom length for connection
Definition NBEdge.h:246
bool uncontrolled
check if Connection is uncontrolled
Definition NBEdge.h:298
PositionVector customShape
custom shape for connection
Definition NBEdge.h:249
bool mayDefinitelyPass
Information about being definitely free to drive (on-ramps)
Definition NBEdge.h:228
double contPos
custom position for internal junction on this connection
Definition NBEdge.h:234
double visibility
custom foe visiblity for connection
Definition NBEdge.h:237
An (internal) definition of a single lane of an edge.
Definition NBEdge.h:143
double width
This lane's width.
Definition NBEdge.h:176
double endOffset
This lane's offset to the intersection begin.
Definition NBEdge.h:169
SVCPermissions preferred
List of vehicle types that are preferred on this lane.
Definition NBEdge.h:160
double speed
The speed allowed on this lane.
Definition NBEdge.h:151
double friction
The friction on this lane.
Definition NBEdge.h:154
SVCPermissions permissions
List of vehicle types that are allowed on this lane.
Definition NBEdge.h:157