Eclipse SUMO - Simulation of Urban MObility
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-2024 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 #include <config.h>
22 
23 #include <netedit/GNENet.h>
24 #include <netedit/GNEUndoList.h>
25 #include <netedit/GNEViewNet.h>
26 #include <netedit/GNEViewParent.h>
42 #include <utils/gui/div/GLHelper.h>
46 
47 #include "GNEConnection.h"
48 #include "GNECrossing.h"
49 #include "GNEEdge.h"
50 #include "GNEEdgeType.h"
51 #include "GNELaneType.h"
52 #include "GNEEdgeTemplate.h"
53 #include "GNELaneTemplate.h"
54 
55 
56 //#define DEBUG_SMOOTH_GEOM
57 //#define DEBUGCOND(obj) (true)
58 #define VEHICLE_GAP 1
59 #define ENDPOINT_TOLERANCE 2
60 
61 // ===========================================================================
62 // static
63 // ===========================================================================
66 
67 // ===========================================================================
68 // members methods
69 // ===========================================================================
70 
71 GNEEdge::GNEEdge(GNENet* net, NBEdge* nbe, bool wasSplit, bool loaded):
72  GNENetworkElement(net, nbe->getID(), GLO_EDGE, SUMO_TAG_EDGE, GUIIconSubSys::getIcon(GUIIcon::EDGE), {
75 },
76 {}, {}, {}, {}, {}),
77 myNBEdge(nbe),
78 myLanes(0),
79 myAmResponsible(false),
80 myWasSplit(wasSplit),
81 myConnectionStatus(loaded ? FEATURE_LOADED : FEATURE_GUESSED),
82 myUpdateGeometry(true) {
83  // Create lanes
84  int numLanes = myNBEdge->getNumLanes();
85  myLanes.reserve(numLanes);
86  for (int i = 0; i < numLanes; i++) {
87  myLanes.push_back(new GNELane(this, i));
88  myLanes.back()->incRef("GNEEdge::GNEEdge");
89  }
90  // update Lane geometries
91  for (const auto& lane : myLanes) {
92  lane->updateGeometry();
93  }
94  // update centering boundary without updating grid
95  updateCenteringBoundary(false);
96 }
97 
98 
100  // Delete references to this edge in lanes
101  for (const auto& lane : myLanes) {
102  lane->decRef("GNEEdge::~GNEEdge");
103  if (lane->unreferenced()) {
104  // check if remove it from Attribute Carriers
105  if (myNet->getAttributeCarriers()->getLanes().count(lane) > 0) {
107  }
108  // show extra information for tests
109  WRITE_DEBUG("Deleting unreferenced " + lane->getTagStr() + " '" + lane->getID() + "' in GNEEdge destructor");
110  delete lane;
111  }
112  }
113  // delete references to this edge in connections
114  for (const auto& connection : myGNEConnections) {
115  connection->decRef("GNEEdge::~GNEEdge");
116  if (connection->unreferenced()) {
117  // check if remove it from Attribute Carriers
118  if (myNet->getAttributeCarriers()->getConnections().count(connection) > 0) {
120  }
121  // show extra information for tests
122  WRITE_DEBUG("Deleting unreferenced " + connection->getTagStr() + " '" + connection->getID() + "' in GNEEdge destructor");
123  delete connection;
124  }
125  }
126  if (myAmResponsible) {
127  delete myNBEdge;
128  }
129 }
130 
131 
132 bool
134  if (getFromJunction()->getNBNode()->getPosition() != getToJunction()->getNBNode()->getPosition()) {
135  return true;
136  } else {
137  return false;
138  }
139 }
140 
141 
142 std::string
144  return TLF("Parent junctions are in the same position: %, %",
145  toString(getFromJunction()->getNBNode()->getPosition().x()),
146  toString(getFromJunction()->getNBNode()->getPosition().y()));
147 }
148 
149 
150 void
152  // first check if myUpdateGeometry flag is enabled
153  if (myUpdateGeometry) {
154  // Update geometry of lanes
155  for (const auto& lane : myLanes) {
156  lane->updateGeometry();
157  }
158  // Update geometry of connections
159  for (const auto& connection : myGNEConnections) {
160  connection->updateGeometry();
161  }
162  // Update geometry of additionals children vinculated to this edge
163  for (const auto& childAdditional : getChildAdditionals()) {
164  childAdditional->updateGeometry();
165  }
166  // Update geometry of additionals demand elements vinculated to this edge
167  for (const auto& childDemandElement : getChildDemandElements()) {
168  childDemandElement->updateGeometry();
169  }
170  // Update geometry of additionals generic datas vinculated to this edge
171  for (const auto& childGenericData : getChildGenericDatas()) {
172  childGenericData->updateGeometry();
173  }
174  // compute geometry of path elements elements vinculated with this edge (depending of showDemandElements)
176  for (const auto& childAdditional : getChildAdditionals()) {
177  childAdditional->computePathElement();
178  }
179  for (const auto& childDemandElement : getChildDemandElements()) {
180  childDemandElement->computePathElement();
181  }
182  for (const auto& childGenericData : getChildGenericDatas()) {
183  childGenericData->computePathElement();
184  }
185  }
186  }
187  // update vehicle geometry
189  // update stack labels
193 }
194 
195 
196 Position
198  return myLanes.front()->getPositionInView();
199 }
200 
201 
202 bool
204  // get modes and viewParent (for code legibility)
205  const auto& modes = myNet->getViewNet()->getEditModes();
206  const auto& viewParent = myNet->getViewNet()->getViewParent();
207  // continue depending of current status
208  if (myNet->getViewNet()->getInspectedAttributeCarriers().size() == 1) {
209  // get inspected element
210  const auto inspectedAC = myNet->getViewNet()->getInspectedAttributeCarriers().front();
211  // check if starts in this edge
212  if (inspectedAC->getTagProperty().vehicleEdges() && inspectedAC->hasAttribute(SUMO_ATTR_FROM) && (inspectedAC->getAttribute(SUMO_ATTR_FROM) == getID())) {
213  return true;
214  }
215  } else if (modes.isCurrentSupermodeDemand()) {
216  // get current GNEPlanCreator
217  GNEPlanCreator* planCreator = nullptr;
218  if (modes.demandEditMode == DemandEditMode::DEMAND_PERSON) {
219  planCreator = viewParent->getPersonFrame()->getPlanCreator();
220  } else if (modes.demandEditMode == DemandEditMode::DEMAND_PERSONPLAN) {
221  planCreator = viewParent->getPersonPlanFrame()->getPlanCreator();
222  } else if (modes.demandEditMode == DemandEditMode::DEMAND_CONTAINER) {
223  planCreator = viewParent->getContainerFrame()->getPlanCreator();
224  } else if (modes.demandEditMode == DemandEditMode::DEMAND_CONTAINERPLAN) {
225  planCreator = viewParent->getContainerPlanFrame()->getPlanCreator();
226  }
227  // continue depending of planCreator
228  if (planCreator) {
229  if (planCreator->getPlanParameteres().fromEdge == getID()) {
230  return true;
231  }
232  } else if (modes.demandEditMode == DemandEditMode::DEMAND_VEHICLE) {
233  const auto& selectedEdges = viewParent->getVehicleFrame()->getPathCreator()->getSelectedEdges();
234  // check if this is the first selected edge
235  if ((selectedEdges.size() > 0) && (selectedEdges.front() == this)) {
236  return true;
237  }
238  }
239  } else if (modes.isCurrentSupermodeData()) {
240  // get TAZRelDataFrame
241  const auto& getEdgeRelDataFrame = viewParent->getEdgeRelDataFrame();
242  if (getEdgeRelDataFrame->shown()) {
243  // check first Edge
244  if (getEdgeRelDataFrame->getPathCreator()->getSelectedEdges().empty()) {
246  } else if (getEdgeRelDataFrame->getPathCreator()->getSelectedEdges().front() == this) {
247  return true;
248  }
249  }
250  }
251  // nothing to draw
252  return false;
253 }
254 
255 
256 bool
258  // get modes and viewParent (for code legibility)
259  const auto& modes = myNet->getViewNet()->getEditModes();
260  const auto& viewParent = myNet->getViewNet()->getViewParent();
261  // continue depending of current status
262  if (myNet->getViewNet()->getInspectedAttributeCarriers().size() == 1) {
263  // get inspected element
264  const auto inspectedAC = myNet->getViewNet()->getInspectedAttributeCarriers().front();
265  // check if starts in this edge
266  if (inspectedAC->getTagProperty().vehicleEdges() && inspectedAC->hasAttribute(SUMO_ATTR_TO) && (inspectedAC->getAttribute(SUMO_ATTR_TO) == getID())) {
267  return true;
268  }
269  } else if (modes.isCurrentSupermodeDemand()) {
270  // get current GNEPlanCreator
271  GNEPlanCreator* planCreator = nullptr;
272  if (modes.demandEditMode == DemandEditMode::DEMAND_PERSON) {
273  planCreator = viewParent->getPersonFrame()->getPlanCreator();
274  } else if (modes.demandEditMode == DemandEditMode::DEMAND_PERSONPLAN) {
275  planCreator = viewParent->getPersonPlanFrame()->getPlanCreator();
276  } else if (modes.demandEditMode == DemandEditMode::DEMAND_CONTAINER) {
277  planCreator = viewParent->getContainerFrame()->getPlanCreator();
278  } else if (modes.demandEditMode == DemandEditMode::DEMAND_CONTAINERPLAN) {
279  planCreator = viewParent->getContainerPlanFrame()->getPlanCreator();
280  }
281  // continue depending of planCreator
282  if (planCreator) {
283  if (planCreator->getPlanParameteres().toEdge == getID()) {
284  return true;
285  }
286  } else if (modes.demandEditMode == DemandEditMode::DEMAND_VEHICLE) {
287  const auto& selectedEdges = viewParent->getVehicleFrame()->getPathCreator()->getSelectedEdges();
288  // check if this is the last selected edge
289  if ((selectedEdges.size() > 1) && (selectedEdges.back() == this)) {
290  return true;
291  }
292  }
293  } else if (modes.isCurrentSupermodeData()) {
294  // get TAZRelDataFrame
295  const auto& getEdgeRelDataFrame = viewParent->getEdgeRelDataFrame();
296  if (getEdgeRelDataFrame->shown()) {
297  // check first Edge
298  if (getEdgeRelDataFrame->getPathCreator()->getSelectedEdges().empty()) {
300  } else if (getEdgeRelDataFrame->getPathCreator()->getSelectedEdges().back() == this) {
301  return true;
302  }
303  }
304  }
305  // nothing to draw
306  return false;
307 }
308 
309 
310 bool
312  return false;
313 }
314 
315 
316 bool
318  // get modes and viewParent (for code legibility)
319  const auto& modes = myNet->getViewNet()->getEditModes();
320  const auto& viewParent = myNet->getViewNet()->getViewParent();
321  const auto& viewObjectsSelector = myNet->getViewNet()->getViewObjectsSelector();
322  if (modes.isCurrentSupermodeDemand()) {
323  // get current plan selector
324  GNEPlanSelector* planSelector = nullptr;
325  if (modes.demandEditMode == DemandEditMode::DEMAND_PERSON) {
326  planSelector = viewParent->getPersonFrame()->getPlanSelector();
327  } else if (modes.demandEditMode == DemandEditMode::DEMAND_PERSONPLAN) {
328  planSelector = viewParent->getPersonPlanFrame()->getPlanSelector();
329  } else if (modes.demandEditMode == DemandEditMode::DEMAND_CONTAINER) {
330  planSelector = viewParent->getContainerFrame()->getPlanSelector();
331  } else if (modes.demandEditMode == DemandEditMode::DEMAND_CONTAINERPLAN) {
332  planSelector = viewParent->getContainerPlanFrame()->getPlanSelector();
333  }
334  // continue depending of plan selector
335  if (planSelector && planSelector->markEdges() && (viewObjectsSelector.getEdgeFront() == this)) {
336  if (viewObjectsSelector.getAttributeCarrierFront()->getTagProperty().isStoppingPlace()) {
337  return false;
338  } else if (viewObjectsSelector.getAttributeCarrierFront()->getTagProperty().isTAZElement()) {
339  return false;
340  } else if (viewObjectsSelector.getAttributeCarrierFront()->getTagProperty().getTag() == SUMO_TAG_JUNCTION) {
341  return false;
342  } else {
343  return true;
344  }
345  } else if (modes.demandEditMode == DemandEditMode::DEMAND_VEHICLE) {
346  // get current vehicle template
347  const auto& vehicleTemplate = viewParent->getVehicleFrame()->getVehicleTagSelector()->getCurrentTemplateAC();
348  // check if vehicle can be placed over from-to TAZs
349  if (vehicleTemplate && vehicleTemplate->getTagProperty().vehicleEdges()) {
350  return myNet->getViewNet()->getViewObjectsSelector().getEdgeFront() == this;
351  }
352  }
353  }
354  return false;
355 }
356 
357 
358 bool
360  // first check if we're selecting edges or lanes
361  if (myNet->getViewNet()->checkSelectEdges()) {
362  // get edit modes
363  const auto& editModes = myNet->getViewNet()->getEditModes();
364  // check if we're in delete mode
365  if (editModes.isCurrentSupermodeNetwork() && (editModes.networkEditMode == NetworkEditMode::NETWORK_DELETE)) {
366  // check lanes
367  for (const auto& lane : myLanes) {
370  return true;
371  }
372  }
373  // check edge
376  return true;
377  }
378  // nothing to draw
379  return false;
380  } else {
381  return false;
382  }
383  } else {
384  return false;
385  }
386 }
387 
388 
389 bool
391  // first check if we're selecting edges or lanes
392  if (myNet->getViewNet()->checkSelectEdges()) {
393  // get edit modes
394  const auto& editModes = myNet->getViewNet()->getEditModes();
395  // check if we're in select mode
396  if (editModes.isCurrentSupermodeNetwork() && (editModes.networkEditMode == NetworkEditMode::NETWORK_SELECT)) {
397  // check lanes
398  for (const auto& lane : myLanes) {
401  return true;
402  }
403  }
404  // check edge
407  return true;
408  }
409  // nothing to draw
410  return false;
411  } else {
412  return false;
413  }
414  } else {
415  return false;
416  }
417 }
418 
419 
420 bool
422  // get edit modes
423  const auto& editModes = myNet->getViewNet()->getEditModes();
424  // check if we're in move mode
425  if (!myNet->getViewNet()->isCurrentlyMovingElements() && editModes.isCurrentSupermodeNetwork() &&
426  (editModes.networkEditMode == NetworkEditMode::NETWORK_MOVE)) {
427  // check if we're editing this network element
429  if (editedNetworkElement) {
430  if (editedNetworkElement == this) {
431  return true;
432  } else {
433  // check lanes
434  for (const auto& lane : myLanes) {
435  if (editedNetworkElement == lane) {
436  return true;
437  }
438  }
439  }
440  } else {
441  // check lanes
442  for (const auto& lane : myLanes) {
445  return true;
446  }
447  }
448  // check edge
451  return true;
452  }
453  }
454  // nothing to draw
455  return false;
456  } else {
457  return false;
458  }
459 }
460 
461 
464  // get geometry point radius
465  const double geometryPointRadius = getGeometryPointRadius();
466  // check if edge is selected
468  // check if both junctions are selected
473  } else if (getToJunction()->isAttributeCarrierSelected()) {
477  // special case: when only a single edge is selected, move all shape points (including custom end points)
479  } else {
480  // synchronized movement of a single point
481  return processNoneJunctionSelected(geometryPointRadius);
482  }
483  } else {
484  // calculate move shape operation (because there are only an edge selected)
485  return calculateMoveShapeOperation(this, myNBEdge->getGeometry(), false);
486  }
487  } else {
488  // calculate move shape operation
489  return calculateMoveShapeOperation(this, myNBEdge->getGeometry(), false);
490  }
491 }
492 
493 
494 void
495 GNEEdge::removeGeometryPoint(const Position clickedPosition, GNEUndoList* undoList) {
496  // get geometry point radius
497  const double geometryPointRadius = getGeometryPointRadius();
498  // declare shape to move
500  // obtain flags for start and end positions
501  const bool customStartPosition = (myNBEdge->getGeometry().front().distanceSquaredTo2D(getFromJunction()->getNBNode()->getPosition()) > ENDPOINT_TOLERANCE);
502  const bool customEndPosition = (myNBEdge->getGeometry().back().distanceSquaredTo2D(getToJunction()->getNBNode()->getPosition()) > ENDPOINT_TOLERANCE);
503  // get variable for last index
504  const int lastIndex = (int)myNBEdge->getGeometry().size() - 1;
505  // flag to enable/disable remove geometry point
506  bool removeGeometryPoint = true;
507  // obtain index
508  const int index = myNBEdge->getGeometry().indexOfClosest(clickedPosition, true);
509  // check index
510  if (index == -1) {
511  removeGeometryPoint = false;
512  }
513  // check distance
514  if (shape[index].distanceSquaredTo2D(clickedPosition) > (geometryPointRadius * geometryPointRadius)) {
515  removeGeometryPoint = false;
516  }
517  // check custom start position
518  if (!customStartPosition && (index == 0)) {
519  removeGeometryPoint = false;
520  }
521  // check custom end position
522  if (!customEndPosition && (index == lastIndex)) {
523  removeGeometryPoint = false;
524  }
525  // check if we can remove geometry point
526  if (removeGeometryPoint) {
527  // check if we're removing first geometry proint
528  if (index == 0) {
529  // commit new geometry start
530  undoList->begin(this, "remove first geometry point of " + getTagStr());
532  undoList->end();
533  } else if (index == lastIndex) {
534  // commit new geometry end
535  undoList->begin(this, "remove last geometry point of " + getTagStr());
537  undoList->end();
538  } else {
539  // remove geometry point
540  shape.erase(shape.begin() + index);
541  // get innen shape
542  shape.pop_front();
543  shape.pop_back();
544  // remove double points
545  shape.removeDoublePoints((geometryPointRadius * geometryPointRadius));
546  // commit new shape
547  undoList->begin(this, "remove geometry point of " + getTagStr());
549  undoList->end();
550  }
551  }
552 }
553 
554 
555 bool
557  if (myNBEdge->getGeometry().front().distanceSquaredTo2D(getFromJunction()->getNBNode()->getPosition()) > ENDPOINT_TOLERANCE) {
558  return true;
559  } else if (myNBEdge->getGeometry().back().distanceSquaredTo2D(getToJunction()->getNBNode()->getPosition()) > ENDPOINT_TOLERANCE) {
560  return true;
561  } else {
562  return false;
563  }
564 }
565 
566 
567 bool
569  // get geometry point radius
570  const double geometryPointRadius = getGeometryPointRadius();
571  if (myNBEdge->getGeometry().front().distanceSquaredTo2D(getFromJunction()->getNBNode()->getPosition()) > ENDPOINT_TOLERANCE) {
572  return (myNBEdge->getGeometry().front().distanceSquaredTo2D(pos) < (geometryPointRadius * geometryPointRadius));
573  } else {
574  return false;
575  }
576 }
577 
578 
579 bool
581  // get geometry point radius
582  const double geometryPointRadius = getGeometryPointRadius();
583  if (myNBEdge->getGeometry().back().distanceSquaredTo2D(getToJunction()->getNBNode()->getPosition()) > ENDPOINT_TOLERANCE) {
584  return (myNBEdge->getGeometry().back().distanceSquaredTo2D(pos) < (geometryPointRadius * geometryPointRadius));
585  } else {
586  return false;
587  }
588 }
589 
590 
591 bool
593  // get geometry point radius
594  const auto geometryPointRadius = getGeometryPointRadius();
595  // first check inner geometry
596  const PositionVector innenShape = myNBEdge->getInnerGeometry();
597  // iterate over geometry point
598  for (const auto& geometryPoint : innenShape) {
599  if (geometryPoint.distanceSquaredTo2D(pos) < (geometryPointRadius * geometryPointRadius)) {
600  return true;
601  }
602  }
603  // check start and end shapes
604  if (clickedOverShapeStart(pos) || clickedOverShapeEnd(pos)) {
605  return true;
606  } else {
607  return false;
608  }
609 }
610 
611 
612 void
614  Position delta = junction->getNBNode()->getPosition() - origPos;
616  // geometry endpoint need not equal junction position hence we modify it with delta
617  if (junction == getFromJunction()) {
618  geom[0].add(delta);
619  } else {
620  geom[-1].add(delta);
621  }
622  setGeometry(geom, false);
623 }
624 
625 
626 double
628  return s.addSize.getExaggeration(s, this);
629 }
630 
631 
632 Boundary
634  return myEdgeBoundary;
635 }
636 
637 
638 void
639 GNEEdge::updateCenteringBoundary(const bool updateGrid) {
640  // Remove object from net
641  if (updateGrid) {
643  }
644  // first add edge boundary
646  // add lane boundaries
647  for (const auto& lane : myLanes) {
648  const auto laneBoundary = lane->getCenteringBoundary();
649  if (laneBoundary.isInitialised()) {
650  myEdgeBoundary.add(laneBoundary);
651  // add additional and demand boundaries
652  for (const auto& additional : lane->getChildAdditionals()) {
653  const auto additionalBoundary = additional->getCenteringBoundary();
654  if (additionalBoundary.isInitialised()) {
655  myEdgeBoundary.add(additional->getCenteringBoundary());
656  }
657  }
658  }
659  }
660  // add additional and demand boundaries
661  for (const auto& additional : getChildAdditionals()) {
662  const auto additionalBoundary = additional->getCenteringBoundary();
663  if (additionalBoundary.isInitialised()) {
664  myEdgeBoundary.add(additionalBoundary);
665  }
666  }
667  // add junction positions
670  // grow boundary
671  myEdgeBoundary.grow(5);
672  // add object into net
673  if (updateGrid) {
674  myNet->addGLObjectIntoGrid(this);
675  }
676 }
677 
678 
679 const std::string
681  return myNBEdge->getStreetName();
682 }
683 
684 
687  // if we call this function, that's mean that we're clicked over a edge geometry point, then
688  // open the popup dialog of the lane[0] (back)
689  return myLanes.back()->getPopUpMenu(app, parent);
690 }
691 
692 
693 std::vector<GNEEdge*>
696 }
697 
698 
699 void
701  // check drawing boundary selection and size boundary
703  // draw boundary
705  // get detail level from the first lane
706  const auto d = myLanes.front()->getDrawingConstants()->getDetail();
707  // check if draw details
708  if (!s.drawForViewObjectsHandler) {
709  // draw geometry points
711  // draw edge shape (a red line only visible if lane shape is strange)
712  drawEdgeShape(s, d);
713  // draw edge stopOffset
714  drawLaneStopOffset(s, d);
715  // draw edge name
716  drawEdgeName(s);
717  // draw lock icon
719  // draw dotted contour
721  }
722  // calculate edge contour (always before children)
723  calculateEdgeContour(s, d);
724  // draw lanes
725  for (const auto& lane : myLanes) {
726  lane->drawGL(s);
727  }
728  // draw junctions
729  getFromJunction()->drawGL(s);
730  getToJunction()->drawGL(s);
731  // draw childrens
732  drawChildrens(s);
733  }
734 }
735 
736 
737 void
739  // Check if edge can be deleted
741  myNet->deleteEdge(this, myNet->getViewNet()->getUndoList(), false);
742  }
743 }
744 
745 
746 void
748  updateGeometry();
749 }
750 
751 
752 NBEdge*
754  return myNBEdge;
755 }
756 
757 
758 Position
759 GNEEdge::getSplitPos(const Position& clickPos) {
760  // get geometry point radius
761  const double geometryPointRadius = getGeometryPointRadius();
762  const PositionVector& geom = myNBEdge->getGeometry();
763  int index = geom.indexOfClosest(clickPos, true);
764  if (geom[index].distanceSquaredTo2D(clickPos) < (geometryPointRadius * geometryPointRadius)) {
765  // split at existing geometry point
766  return myNet->getViewNet()->snapToActiveGrid(geom[index]);
767  } else {
768  // split straight between the next two points
770  }
771 }
772 
773 
774 void
776  // get geometry point radius
777  const double geometryPointRadius = getGeometryPointRadius();
778  if ((myNBEdge->getGeometry().front().distanceSquaredTo2D(getFromJunction()->getNBNode()->getPosition()) > ENDPOINT_TOLERANCE) &&
779  (myNBEdge->getGeometry().front().distanceSquaredTo2D(pos) < (geometryPointRadius * geometryPointRadius))) {
780  undoList->begin(this, "remove endpoint");
781  setAttribute(GNE_ATTR_SHAPE_START, "", undoList);
782  undoList->end();
783  } else if ((myNBEdge->getGeometry().back().distanceSquaredTo2D(getToJunction()->getNBNode()->getPosition()) > ENDPOINT_TOLERANCE) &&
784  (myNBEdge->getGeometry().back().distanceSquaredTo2D(pos) < (geometryPointRadius * geometryPointRadius))) {
785  undoList->begin(this, "remove endpoint");
786  setAttribute(GNE_ATTR_SHAPE_END, "", undoList);
787  undoList->end();
788  } else {
789  // we need to create new Start/End position over Edge shape, not over clicked position
791  if (offset != GeomHelper::INVALID_OFFSET) {
793  // calculate position over edge shape relative to clicked position
794  Position newPos = geom.positionAtOffset2D(offset);
795  // snap new position to grid
796  newPos = myNet->getViewNet()->snapToActiveGrid(newPos);
797  undoList->begin(this, "set endpoint");
798  const int index = geom.indexOfClosest(pos, true);
799  const Position destPos = getToJunction()->getNBNode()->getPosition();
800  const Position sourcePos = getFromJunction()->getNBNode()->getPosition();
801  if (pos.distanceTo2D(destPos) < pos.distanceTo2D(sourcePos)) {
802  // check if snap to existing geometrypoint
803  if (geom[index].distanceSquaredTo2D(pos) < (geometryPointRadius * geometryPointRadius)) {
804  newPos = geom[index];
805  // remove existent geometry point to avoid double points
806  removeGeometryPoint(newPos, undoList);
807  }
808  setAttribute(GNE_ATTR_SHAPE_END, toString(newPos), undoList);
810  } else {
811  // check if snap to existing geometry point
812  if (geom[index].distanceSquaredTo2D(pos) < (geometryPointRadius * geometryPointRadius)) {
813  newPos = geom[index];
814  // remove existent geometry point to avoid double points
815  removeGeometryPoint(newPos, undoList);
816  }
817  setAttribute(GNE_ATTR_SHAPE_START, toString(newPos), undoList);
819  }
820  undoList->end();
821  }
822  }
823 }
824 
825 
826 void
828  Position destPos = getToJunction()->getNBNode()->getPosition();
829  Position sourcePos = getFromJunction()->getNBNode()->getPosition();
830  if (pos.distanceTo2D(destPos) < pos.distanceTo2D(sourcePos)) {
831  setAttribute(GNE_ATTR_SHAPE_END, toString(destPos), undoList);
833  } else {
834  setAttribute(GNE_ATTR_SHAPE_START, toString(sourcePos), undoList);
836  }
837 }
838 
839 
840 void
842  // reset shape start
843  setAttribute(GNE_ATTR_SHAPE_END, "", undoList);
845  // reset shape end
846  setAttribute(GNE_ATTR_SHAPE_START, "", undoList);
848 }
849 
850 void
852  // set new geometry
853  const bool lefthand = OptionsCont::getOptions().getBool("lefthand");
854  if (lefthand) {
855  geom.mirrorX();
856  myNBEdge->mirrorX();
857  }
858  myNBEdge->setGeometry(geom, inner);
859  if (lefthand) {
860  myNBEdge->mirrorX();
861  }
862  // update geometry
863  updateGeometry();
864  // invalidate junction source shape
866  // iterate over first parent junction edges and update geometry
867  for (const auto& edge : getFromJunction()->getGNEIncomingEdges()) {
868  edge->updateGeometry();
869  }
870  for (const auto& edge : getFromJunction()->getGNEOutgoingEdges()) {
871  edge->updateGeometry();
872  }
873  // invalidate junction destination shape
875  // iterate over second parent junction edges and update geometry
876  for (const auto& edge : getToJunction()->getGNEIncomingEdges()) {
877  edge->updateGeometry();
878  }
879  for (const auto& edge : getToJunction()->getGNEOutgoingEdges()) {
880  edge->updateGeometry();
881  }
882 }
883 
884 
885 const Position
887  PositionVector laneShape = myLanes.front()->getLaneShape();
888  laneShape.move2side(myLanes.front()->getParentEdge()->getNBEdge()->getLaneWidth(myLanes.front()->getIndex()) / 2);
889  return laneShape.front();
890 }
891 
892 
893 const Position
895  PositionVector laneShape = myLanes.back()->getLaneShape();
896  laneShape.move2side(-1 * myLanes.back()->getParentEdge()->getNBEdge()->getLaneWidth(myLanes.back()->getIndex()) / 2);
897  return laneShape.front();
898 }
899 
900 
901 const Position
903  PositionVector laneShape = myLanes.front()->getLaneShape();
904  laneShape.move2side(myLanes.front()->getParentEdge()->getNBEdge()->getLaneWidth(myLanes.front()->getIndex()) / 2);
905  return laneShape.back();
906 }
907 
908 
909 const Position
911  PositionVector laneShape = myLanes.back()->getLaneShape();
912  laneShape.move2side(-1 * myLanes.back()->getParentEdge()->getNBEdge()->getLaneWidth(myLanes.back()->getIndex()) / 2);
913  return laneShape.back();
914 }
915 
916 void
917 GNEEdge::remakeGNEConnections(bool junctionsReady) {
918  // create new and removed unused GNEConnections
919  const std::vector<NBEdge::Connection>& connections = myNBEdge->getConnections();
920  // create a vector to keep retrieved and created connections
921  std::vector<GNEConnection*> retrievedConnections;
922  // iterate over NBEdge::Connections of GNEEdge
923  for (const auto& connection : connections) {
924  // retrieve existent GNEConnection, or create it
925  GNEConnection* retrievedGNEConnection = retrieveGNEConnection(connection.fromLane, connection.toEdge, connection.toLane);
926  if (junctionsReady) {
927  retrievedGNEConnection->updateLinkState();
928  }
929  retrievedConnections.push_back(retrievedGNEConnection);
930  // check if previously this GNEConnections exists, and if true, remove it from myGNEConnections
931  std::vector<GNEConnection*>::iterator retrievedExists = std::find(myGNEConnections.begin(), myGNEConnections.end(), retrievedGNEConnection);
932  if (retrievedExists != myGNEConnections.end()) {
933  myGNEConnections.erase(retrievedExists);
934  } else {
935  // include reference to created GNEConnection
936  retrievedGNEConnection->incRef("GNEEdge::remakeGNEConnections");
937  }
938  // mark it as deprecated
939  retrievedGNEConnection->markConnectionGeometryDeprecated();
940  }
941  // delete non retrieved GNEConnections
942  for (const auto& connection : myGNEConnections) {
943  // decrease reference
944  connection->decRef();
945  // remove it from network
946  myNet->removeGLObjectFromGrid(connection);
947  // and from AttributeCarriers
948  if (myNet->getAttributeCarriers()->getConnections().count(connection) > 0) {
950  }
951  // delete GNEConnection if is unreferenced
952  if (connection->unreferenced()) {
953 
954  // show extra information for tests
955  WRITE_DEBUG("Deleting unreferenced " + connection->getTagStr() + " '" + connection->getID() + "' in rebuildGNEConnections()");
956  delete connection;
957  }
958  }
959  // copy retrieved (existent and created) GNECrossings to myGNEConnections
960  myGNEConnections = retrievedConnections;
961 }
962 
963 
964 void
966  // Drop all existents connections that aren't referenced anymore
967  for (const auto& connection : myGNEConnections) {
968  // check if connection is selected
969  if (connection->isAttributeCarrierSelected()) {
970  connection->unselectAttributeCarrier();
971  }
972  // Dec reference of connection
973  connection->decRef("GNEEdge::clearGNEConnections");
974  // remove it from network
975  myNet->removeGLObjectFromGrid(connection);
976  // and from AttributeCarriers
977  if (myNet->getAttributeCarriers()->getConnections().count(connection) > 0) {
979  }
980  // Delete GNEConnectionToErase if is unreferenced
981  if (connection->unreferenced()) {
982  // show extra information for tests
983  WRITE_DEBUG("Deleting unreferenced " + connection->getTagStr() + " '" + connection->getID() + "' in clearGNEConnections()");
984  delete connection;
985  }
986  }
987  myGNEConnections.clear();
988 }
989 
990 
991 int
993  std::vector<GNEAdditional*> routeProbes;
994  for (auto i : getChildAdditionals()) {
995  if (i->getTagProperty().getTag() == routeProbe->getTagProperty().getTag()) {
996  routeProbes.push_back(i);
997  }
998  }
999  // return index of routeProbe in routeProbes vector
1000  auto it = std::find(routeProbes.begin(), routeProbes.end(), routeProbe);
1001  if (it == routeProbes.end()) {
1002  return -1;
1003  } else {
1004  return (int)(it - routeProbes.begin());
1005  }
1006 }
1007 
1008 
1009 std::vector<GNECrossing*>
1011  std::vector<GNECrossing*> crossings;
1012  for (auto i : getFromJunction()->getGNECrossings()) {
1013  if (i->checkEdgeBelong(this)) {
1014  crossings.push_back(i);
1015  }
1016  }
1017  for (auto i : getToJunction()->getGNECrossings()) {
1018  if (i->checkEdgeBelong(this)) {
1019  crossings.push_back(i);
1020  }
1021  }
1022  return crossings;
1023 }
1024 
1025 
1026 void
1027 GNEEdge::copyTemplate(const GNEEdgeTemplate* edgeTemplate, GNEUndoList* undoList) {
1028  // copy edge-specific attributes
1029  for (const auto& attProperty : myTagProperty) {
1030  if (attProperty.isCopyable() && isValid(attProperty.getAttr(), edgeTemplate->getAttribute(attProperty.getAttr()))) {
1031  setAttribute(attProperty.getAttr(), edgeTemplate->getAttribute(attProperty.getAttr()), undoList);
1032  }
1033  }
1034  // also copy parameters
1036  // copy lane attributes as well
1037  for (int i = 0; i < (int)myLanes.size(); i++) {
1038  for (const auto& attProperty : edgeTemplate->getLaneTemplates().at(i)->getTagProperty()) {
1039  if (attProperty.isCopyable() && myLanes[i]->isValid(attProperty.getAttr(), edgeTemplate->getLaneTemplates().at(i)->getAttribute(attProperty.getAttr()))) {
1040  myLanes[i]->setAttribute(attProperty.getAttr(), edgeTemplate->getLaneTemplates().at(i)->getAttribute(attProperty.getAttr()), undoList);
1041  }
1042  }
1043  // also copy parameters
1044  myLanes[i]->setAttribute(GNE_ATTR_PARAMETERS, edgeTemplate->getLaneTemplates().at(i)->getAttribute(GNE_ATTR_PARAMETERS), undoList);
1045  }
1046 }
1047 
1048 
1049 void
1050 GNEEdge::copyEdgeType(const GNEEdgeType* edgeType, GNEUndoList* undoList) {
1051  // get tag properties
1052  const auto& edgeProperties = getTagProperty(SUMO_TAG_EDGE);
1053  const auto& laneProperties = getTagProperty(SUMO_TAG_LANE);
1054  const auto& edgeTypeProperties = getTagProperty(SUMO_TAG_TYPE);
1055  const auto& laneTypeProperties = getTagProperty(SUMO_TAG_LANETYPE);
1056  // set type (only for info)
1057  setAttribute(SUMO_ATTR_TYPE, edgeType->getAttribute(SUMO_ATTR_ID), undoList);
1058  // copy attributes
1059  for (const auto& attrProperty : edgeTypeProperties) {
1060  if (attrProperty.isCopyable() && edgeProperties.hasAttribute(attrProperty.getAttr())) {
1061  setAttribute(attrProperty.getAttr(), edgeType->getAttribute(attrProperty.getAttr()), undoList);
1062  }
1063  }
1065  // copy lane attributes as well
1066  for (int i = 0; i < (int)myLanes.size(); i++) {
1067  for (const auto& attrProperty : laneTypeProperties) {
1068  if (attrProperty.isCopyable() && laneProperties.hasAttribute(attrProperty.getAttr()) && (edgeType->getLaneTypes().at(i)->getAttribute(attrProperty.getAttr()) != laneTypeProperties.getAttributeProperties(attrProperty.getAttr()).getDefaultValue())) {
1069  myLanes[i]->setAttribute(attrProperty.getAttr(), edgeType->getLaneTypes().at(i)->getAttribute(attrProperty.getAttr()), undoList);
1070  }
1071  }
1072  if (edgeType->getLaneTypes().at(i)->getAttribute(GNE_ATTR_PARAMETERS).size() > 0) {
1073  myLanes[i]->setAttribute(GNE_ATTR_PARAMETERS, edgeType->getLaneTypes().at(i)->getAttribute(GNE_ATTR_PARAMETERS), undoList);
1074  }
1075  }
1076 }
1077 
1078 
1079 std::set<GUIGlID>
1081  std::set<GUIGlID> result;
1082  for (auto i : myLanes) {
1083  result.insert(i->getGlID());
1084  }
1085  return result;
1086 }
1087 
1088 
1089 const std::vector<GNELane*>&
1091  return myLanes;
1092 }
1093 
1094 
1095 const std::vector<GNEConnection*>&
1097  return myGNEConnections;
1098 }
1099 
1100 
1101 bool
1103  return myWasSplit;
1104 }
1105 
1106 
1107 std::string
1109  switch (key) {
1110  case SUMO_ATTR_ID:
1111  return getMicrosimID();
1112  case SUMO_ATTR_FROM:
1114  return getFromJunction()->getID();
1115  case SUMO_ATTR_TO:
1116  case SUMO_ATTR_TO_JUNCTION:
1117  return getToJunction()->getID();
1118  case SUMO_ATTR_NUMLANES:
1119  return toString(myNBEdge->getNumLanes());
1120  case SUMO_ATTR_PRIORITY:
1121  return toString(myNBEdge->getPriority());
1122  case SUMO_ATTR_LENGTH:
1123  return toString(myNBEdge->getFinalLength());
1124  case SUMO_ATTR_TYPE:
1125  return myNBEdge->getTypeID();
1126  case SUMO_ATTR_SHAPE:
1127  return toString(myNBEdge->getInnerGeometry());
1128  case SUMO_ATTR_SPREADTYPE:
1130  case SUMO_ATTR_NAME:
1131  return myNBEdge->getStreetName();
1132  case SUMO_ATTR_ALLOW:
1133  return (getVehicleClassNames(myNBEdge->getPermissions()) + (myNBEdge->hasLaneSpecificPermissions() ? " (combined!)" : ""));
1134  case SUMO_ATTR_DISALLOW: {
1136  }
1137  case SUMO_ATTR_SPEED:
1138  if (myNBEdge->hasLaneSpecificSpeed()) {
1139  return "lane specific";
1140  } else {
1141  return toString(myNBEdge->getSpeed());
1142  }
1143  case SUMO_ATTR_FRICTION:
1145  return "lane specific";
1146  } else {
1147  return toString(myNBEdge->getFriction());
1148  }
1149  case SUMO_ATTR_WIDTH:
1150  if (myNBEdge->hasLaneSpecificWidth()) {
1151  return "lane specific";
1152  } else if (myNBEdge->getLaneWidth() == NBEdge::UNSPECIFIED_WIDTH) {
1153  return "default";
1154  } else {
1155  return toString(myNBEdge->getLaneWidth());
1156  }
1157  case SUMO_ATTR_ENDOFFSET:
1159  return "lane specific";
1160  } else {
1161  return toString(myNBEdge->getEndOffset());
1162  }
1163  case SUMO_ATTR_DISTANCE:
1164  return toString(myNBEdge->getDistance());
1166  return myConnectionStatus;
1167  case GNE_ATTR_SHAPE_START:
1168  if (myNBEdge->getGeometry().front().distanceSquaredTo2D(getFromJunction()->getNBNode()->getPosition()) <= ENDPOINT_TOLERANCE) {
1169  return "";
1170  } else {
1171  return toString(myNBEdge->getGeometry().front());
1172  }
1173  case GNE_ATTR_SHAPE_END:
1174  if (myNBEdge->getGeometry().back().distanceSquaredTo2D(getToJunction()->getNBNode()->getPosition()) <= ENDPOINT_TOLERANCE) {
1175  return "";
1176  } else {
1177  return toString(myNBEdge->getGeometry().back());
1178  }
1179  case GNE_ATTR_BIDIR:
1180  return toString(myNBEdge->getBidiEdge() != nullptr);
1181  case GNE_ATTR_STOPOFFSET:
1186  } else {
1187  return "";
1188  }
1191  case GNE_ATTR_SELECTED:
1193  case GNE_ATTR_PARAMETERS:
1194  return myNBEdge->getParametersStr();
1195  default:
1196  throw InvalidArgument(getTagStr() + " doesn't have an attribute of type '" + toString(key) + "'");
1197  }
1198 }
1199 
1200 
1203  switch (key) {
1204  case SUMO_ATTR_SHAPE:
1205  return myNBEdge->getInnerGeometry();
1206  default:
1207  throw InvalidArgument(getTagStr() + " doesn't have an attribute of type '" + toString(key) + "'");
1208  }
1209 }
1210 
1211 
1212 std::string
1214  std::string result = getAttribute(key);
1215  if ((key == SUMO_ATTR_ALLOW || key == SUMO_ATTR_DISALLOW) && result.find("all") != std::string::npos) {
1216  result += " " + getVehicleClassNames(SVCAll, true);
1217  }
1218  return result;
1219 }
1220 
1221 
1222 void
1223 GNEEdge::setAttribute(SumoXMLAttr key, const std::string& value, GNEUndoList* undoList) {
1224  // get template editor
1226  // check if we have to update template
1227  const bool updateTemplate = templateEditor->getEdgeTemplate() ? (templateEditor->getEdgeTemplate()->getID() == getID()) : false;
1228  switch (key) {
1229  case SUMO_ATTR_WIDTH:
1230  case SUMO_ATTR_ENDOFFSET:
1231  case SUMO_ATTR_SPEED:
1232  case SUMO_ATTR_FRICTION:
1233  case SUMO_ATTR_ALLOW:
1234  case SUMO_ATTR_DISALLOW: {
1235  undoList->begin(this, "change " + getTagStr() + " attribute");
1236  const std::string origValue = myLanes.at(0)->getAttribute(key); // will have intermediate value of "lane specific"
1237  // lane specific attributes need to be changed via lanes to allow undo
1238  for (auto it : myLanes) {
1239  it->setAttribute(key, value, undoList);
1240  }
1241  // ensure that the edge value is also changed. Actually this sets the lane attributes again but it does not matter
1242  GNEChange_Attribute::changeAttribute(this, key, value, origValue, undoList);
1243  undoList->end();
1244  break;
1245  }
1246  case SUMO_ATTR_FROM: {
1247  if (value != getAttribute(key)) {
1248  undoList->begin(this, "change " + getTagStr() + " attribute");
1249  // Remove edge from crossings of junction source
1251  // continue changing from junction
1252  GNEJunction* originalFirstParentJunction = getFromJunction();
1253  getFromJunction()->setLogicValid(false, undoList);
1254  GNEChange_Attribute::changeAttribute(this, key, value, undoList);
1255  getFromJunction()->setLogicValid(false, undoList);
1256  myNet->getAttributeCarriers()->retrieveJunction(value)->setLogicValid(false, undoList);
1257  setAttribute(GNE_ATTR_SHAPE_START, toString(getFromJunction()->getNBNode()->getPosition()), undoList);
1259  undoList->end();
1260  // update geometries of all implicated junctions
1261  originalFirstParentJunction->updateGeometry();
1264  }
1265  break;
1266  }
1267  case SUMO_ATTR_TO: {
1268  if (value != getAttribute(key)) {
1269  undoList->begin(this, "change " + getTagStr() + " attribute");
1270  // Remove edge from crossings of junction destination
1272  // continue changing destination junction
1273  GNEJunction* originalSecondParentJunction = getToJunction();
1274  getToJunction()->setLogicValid(false, undoList);
1275  GNEChange_Attribute::changeAttribute(this, key, value, undoList);
1276  getToJunction()->setLogicValid(false, undoList);
1277  myNet->getAttributeCarriers()->retrieveJunction(value)->setLogicValid(false, undoList);
1278  setAttribute(GNE_ATTR_SHAPE_END, toString(getToJunction()->getNBNode()->getPosition()), undoList);
1280  undoList->end();
1281  // update geometries of all implicated junctions
1282  originalSecondParentJunction->updateGeometry();
1285  }
1286  break;
1287  }
1288  case SUMO_ATTR_ID:
1289  case SUMO_ATTR_PRIORITY:
1290  case SUMO_ATTR_LENGTH:
1291  case SUMO_ATTR_TYPE:
1292  case SUMO_ATTR_SPREADTYPE:
1293  case SUMO_ATTR_DISTANCE:
1295  case GNE_ATTR_SELECTED:
1296  case GNE_ATTR_STOPOFFSET:
1297  // special case for stop offset, because affects to stopOffsetExceptions (#15297)
1298  if (canParse<double>(value) && (parse<double>(value) == 0)) {
1300  }
1301  GNEChange_Attribute::changeAttribute(this, key, value, undoList);
1302  break;
1304  case GNE_ATTR_PARAMETERS:
1305  GNEChange_Attribute::changeAttribute(this, key, value, undoList);
1306  break;
1307  case GNE_ATTR_SHAPE_START:
1308  case GNE_ATTR_SHAPE_END: {
1309  // due to ENDPOINT_TOLERANCE, force change
1310  GNEChange_Attribute::changeAttribute(this, key, value, undoList, true);
1311  break;
1312  }
1313  case SUMO_ATTR_NAME:
1314  // user cares about street names. Make sure they appear in the output
1316  OptionsCont::getOptions().set("output.street-names", "true");
1317  GNEChange_Attribute::changeAttribute(this, key, value, undoList);
1318  break;
1319  case SUMO_ATTR_NUMLANES:
1320  if (value != getAttribute(key)) {
1321  // set num lanes
1322  setNumLanes(parse<int>(value), undoList);
1323  }
1324  break;
1325  case GNE_ATTR_BIDIR:
1326  undoList->begin(this, "change " + getTagStr() + " attribute");
1327  GNEChange_Attribute::changeAttribute(this, key, value, undoList);
1328  if (myNBEdge->getTurnDestination(true) != nullptr) {
1330  GNEChange_Attribute::changeAttribute(bidi, key, value, undoList);
1331  if (myNBEdge->getGeometry() != bidi->getNBEdge()->getGeometry().reverse()
1332  && myNBEdge->getGeometry().size() == 2
1333  && bidi->getNBEdge()->getGeometry().size() == 2
1334  && myNBEdge->getBidiEdge() == nullptr) {
1335  // NBEdge::avoidOverlap was already active so we need to reset the
1336  // geometry to its default
1337  resetBothEndpoint(undoList);
1338  bidi->resetBothEndpoint(undoList);
1339  }
1340  }
1341  undoList->end();
1342  break;
1343  case SUMO_ATTR_SHAPE:
1344  // @note: assumes value of inner geometry!
1345  // actually the geometry is already updated (incrementally
1346  // during mouse movement). We set the restore point to the end
1347  // of the last change-set
1348  GNEChange_Attribute::changeAttribute(this, key, value, undoList);
1349  break;
1350  default:
1351  throw InvalidArgument(getTagStr() + " doesn't have an attribute of type '" + toString(key) + "'");
1352  }
1353  // update template
1354  if (updateTemplate) {
1355  templateEditor->setEdgeTemplate(this);
1356  }
1357 }
1358 
1359 
1360 bool
1361 GNEEdge::isValid(SumoXMLAttr key, const std::string& value) {
1362  switch (key) {
1363  case SUMO_ATTR_ID:
1364  return SUMOXMLDefinitions::isValidNetID(value) && (myNet->getAttributeCarriers()->retrieveEdge(value, false) == nullptr);
1365  case SUMO_ATTR_FROM: {
1366  // check that is a valid ID and is different of ID of junction destination
1367  if (value == getFromJunction()->getID()) {
1368  return true;
1369  } else if (SUMOXMLDefinitions::isValidNetID(value) && (value != getToJunction()->getID())) {
1370  return (myNet->getAttributeCarriers()->retrieveJunction(value, false) != nullptr);
1371  } else {
1372  return false;
1373  }
1374  }
1375  case SUMO_ATTR_TO: {
1376  // check that is a valid ID and is different of ID of junction Source
1377  if (value == getToJunction()->getID()) {
1378  return true;
1379  } else if (SUMOXMLDefinitions::isValidNetID(value) && (value != getFromJunction()->getID())) {
1380  return (myNet->getAttributeCarriers()->retrieveJunction(value, false) != nullptr);
1381  } else {
1382  return false;
1383  }
1384  }
1385  case SUMO_ATTR_SPEED:
1386  return canParse<double>(value) && (parse<double>(value) > 0);
1387  case SUMO_ATTR_FRICTION:
1388  return canParse<double>(value) && (parse<double>(value) > 0);
1389  case SUMO_ATTR_NUMLANES:
1390  return canParse<int>(value) && (parse<double>(value) > 0);
1391  case SUMO_ATTR_PRIORITY:
1392  return canParse<int>(value);
1393  case SUMO_ATTR_LENGTH:
1394  if (value.empty()) {
1395  return true;
1396  } else {
1397  return canParse<double>(value) && ((parse<double>(value) > 0) || (parse<double>(value) == NBEdge::UNSPECIFIED_LOADED_LENGTH));
1398  }
1399  case SUMO_ATTR_ALLOW:
1400  case SUMO_ATTR_DISALLOW:
1401  return canParseVehicleClasses(value);
1402  case SUMO_ATTR_TYPE:
1403  return true;
1404  case SUMO_ATTR_SHAPE:
1405  // empty shapes are allowed
1406  return canParse<PositionVector>(value);
1407  case SUMO_ATTR_SPREADTYPE:
1409  case SUMO_ATTR_NAME:
1410  return true;
1411  case SUMO_ATTR_WIDTH:
1412  if (value.empty() || (value == "default")) {
1413  return true;
1414  } else {
1415  return canParse<double>(value) && ((parse<double>(value) >= -1) || (parse<double>(value) == NBEdge::UNSPECIFIED_WIDTH));
1416  }
1417  case SUMO_ATTR_ENDOFFSET:
1418  return canParse<double>(value) && parse<double>(value) >= 0 && parse<double>(value) < myNBEdge->getLoadedLength();
1419  case SUMO_ATTR_DISTANCE:
1420  if (value.empty()) {
1421  return true;
1422  } else {
1423  return canParse<double>(value);
1424  }
1425  case GNE_ATTR_SHAPE_START: {
1426  if (value.empty()) {
1427  return true;
1428  } else if (canParse<Position>(value)) {
1429  Position shapeStart = parse<Position>(value);
1430  return (shapeStart != myNBEdge->getGeometry()[-1]);
1431  } else {
1432  return false;
1433  }
1434  }
1435  case GNE_ATTR_SHAPE_END: {
1436  if (value.empty()) {
1437  return true;
1438  } else if (canParse<Position>(value)) {
1439  Position shapeEnd = parse<Position>(value);
1440  return (shapeEnd != myNBEdge->getGeometry()[0]);
1441  } else {
1442  return false;
1443  }
1444  }
1445  case GNE_ATTR_BIDIR:
1446  return canParse<bool>(value) && (!parse<bool>(value) || myNBEdge->isBidiEdge(true));
1447  case GNE_ATTR_STOPOFFSET:
1448  if (value.empty()) {
1449  return true;
1450  } else {
1451  return canParse<double>(value) && (parse<double>(value) >= 0);
1452  }
1454  return canParseVehicleClasses(value);
1455  case GNE_ATTR_SELECTED:
1456  return canParse<bool>(value);
1457  case GNE_ATTR_PARAMETERS:
1458  return Parameterised::areParametersValid(value);
1459  default:
1460  throw InvalidArgument(getTagStr() + " doesn't have an attribute of type '" + toString(key) + "'");
1461  }
1462 }
1463 
1464 
1465 bool
1467  switch (key) {
1468  case GNE_ATTR_BIDIR:
1469  return myNBEdge->isBidiEdge(true);
1471  return myNBEdge->myEdgeStopOffset.getOffset() > 0;
1473  return false;
1474  default:
1475  return true;
1476  }
1477 }
1478 
1479 
1480 bool
1482  switch (key) {
1483  case SUMO_ATTR_LENGTH:
1484  return !myNBEdge->hasLoadedLength();
1485  case SUMO_ATTR_WIDTH:
1486  if (myNBEdge->hasLaneSpecificWidth()) {
1487  return false;
1488  } else {
1490  }
1491  default:
1492  return false;
1493  }
1494 }
1495 
1496 
1497 const Parameterised::Map&
1499  return myNBEdge->getParametersMap();
1500 }
1501 
1502 
1503 void
1505  myAmResponsible = newVal;
1506 }
1507 
1508 
1509 GNELane*
1511  // iterate over all NBEdge lanes
1512  for (int i = 0; i < (int)myNBEdge->getLanes().size(); i++) {
1513  // if given VClass is in permissions, return lane
1514  if (myNBEdge->getLanes().at(i).permissions & vClass) {
1515  // return GNELane
1516  return myLanes.at(i);
1517  }
1518  }
1519  // return first lane
1520  return myLanes.front();
1521 }
1522 
1523 
1524 GNELane*
1526  // iterate over all NBEdge lanes
1527  for (int i = 0; i < (int)myNBEdge->getLanes().size(); i++) {
1528  // if given VClass isn't in permissions, return lane
1529  if (~(myNBEdge->getLanes().at(i).permissions) & vClass) {
1530  // return GNELane
1531  return myLanes.at(i);
1532  }
1533  }
1534  // return first lane
1535  return myLanes.front();
1536 }
1537 
1538 
1539 void
1541  // get lane vehicles map
1542  const std::map<const GNELane*, std::vector<GNEDemandElement*> > laneVehiclesMap = getVehiclesOverEdgeMap();
1543  // iterate over every lane
1544  for (const auto& laneVehicle : laneVehiclesMap) {
1545  // obtain total length
1546  double totalLength = 0;
1547  for (const auto& vehicle : laneVehicle.second) {
1548  totalLength += vehicle->getAttributeDouble(SUMO_ATTR_LENGTH) + VEHICLE_GAP;
1549  }
1550  // calculate multiplier for vehicle positions
1551  double multiplier = 1;
1552  const double laneShapeLength = laneVehicle.first->getLaneShape().length();
1553  if (laneShapeLength == 0) {
1554  multiplier = 0;
1555  } else if (totalLength > laneShapeLength) {
1556  multiplier = (laneShapeLength / totalLength);
1557  }
1558  // declare current length
1559  double length = 0;
1560  // iterate over vehicles to calculate position and rotations
1561  for (const auto& vehicle : laneVehicle.second) {
1562  vehicle->updateDemandElementSpreadGeometry(laneVehicle.first, length * multiplier);
1563  // update length
1564  length += vehicle->getAttributeDouble(SUMO_ATTR_LENGTH) + VEHICLE_GAP;
1565  }
1566  }
1567 }
1568 
1569 
1570 void
1572  // get lane vehicles map
1573  const std::map<const GNELane*, std::vector<GNEDemandElement*> > laneVehiclesMap = getVehiclesOverEdgeMap();
1574  // iterate over laneVehiclesMap and obtain a vector with
1575  for (const auto& vehicleMap : laneVehiclesMap) {
1576  // declare map for sort vehicles using their departpos+length position (StackPosition)
1577  std::vector<std::pair<GNEEdge::StackPosition, GNEDemandElement*> > departPosVehicles;
1578  // declare vector of stack demand elements
1579  std::vector<GNEEdge::StackDemandElements> stackedVehicles;
1580  // iterate over vehicles
1581  for (const auto& vehicle : vehicleMap.second) {
1582  // get vehicle's depart pos and length
1583  const double departPos = vehicle->getAttributeDouble(SUMO_ATTR_DEPARTPOS);
1584  const double length = vehicle->getAttributeDouble(SUMO_ATTR_LENGTH);
1585  double posOverLane = vehicle->getAttributeDouble(SUMO_ATTR_DEPARTPOS);
1586  // check if we have to adapt posOverLane
1587  if (posOverLane < 0) {
1588  posOverLane += vehicleMap.first->getLaneShape().length();
1589  }
1590  // make a stack position using departPos and length
1591  departPosVehicles.push_back(std::make_pair(StackPosition(departPos, length), vehicle));
1592  // update depart element geometry
1593  vehicle->updateDemandElementGeometry(vehicleMap.first, posOverLane);
1594  // reset vehicle stack label
1595  vehicle->updateDemandElementStackLabel(0);
1596  }
1597 
1598  // sort departPosVehicles
1599  std::sort(departPosVehicles.begin(), departPosVehicles.end());
1600  // iterate over departPosVehicles
1601  for (const auto& departPosVehicle : departPosVehicles) {
1602  // obtain stack position and vehicle
1603  const GNEEdge::StackPosition& vehicleStackPosition = departPosVehicle.first;
1604  GNEDemandElement* vehicle = departPosVehicle.second;
1605  // if stackedVehicles is empty, add a new StackDemandElements
1606  if (stackedVehicles.empty()) {
1607  stackedVehicles.push_back(GNEEdge::StackDemandElements(vehicleStackPosition, vehicle));
1608  } else if (areStackPositionOverlapped(vehicleStackPosition, stackedVehicles.back().getStackPosition())) {
1609  // add new vehicle to last inserted stackDemandElements
1610  stackedVehicles[stackedVehicles.size() - 1].addDemandElements(vehicle);
1611  } else {
1612  // No overlapping, then add a new StackDemandElements
1613  stackedVehicles.push_back(GNEEdge::StackDemandElements(vehicleStackPosition, vehicle));
1614  }
1615  }
1616  // iterate over stackedVehicles
1617  for (const auto& vehicle : stackedVehicles) {
1618  // only update vehicles with one or more stack
1619  if (vehicle.getDemandElements().size() > 1) {
1620  // set stack labels
1621  vehicle.getDemandElements().front()->updateDemandElementStackLabel((int)vehicle.getDemandElements().size());
1622  }
1623  }
1624  }
1625 }
1626 
1627 
1628 void
1630  // get lane persons map
1631  const std::map<const GNELane*, std::vector<GNEDemandElement*> > lanePersonsMap = getPersonsOverEdgeMap();
1632  // iterate over lanePersonsMap and obtain a vector with
1633  for (const auto& personMap : lanePersonsMap) {
1634  // declare map for sort persons using their departpos+length position (StackPosition)
1635  std::vector<std::pair<GNEEdge::StackPosition, GNEDemandElement*> > departPosPersons;
1636  // declare vector of stack demand elements
1637  std::vector<GNEEdge::StackDemandElements> stackedPersons;
1638  // iterate over persons
1639  for (const auto& person : personMap.second) {
1640  // get person's depart pos and length
1641  const double departPos = person->getAttributeDouble(SUMO_ATTR_DEPARTPOS);
1642  // make a stack position using departPos and length
1643  departPosPersons.push_back(std::make_pair(StackPosition(departPos, 1.8), person));
1644  // update depart element geometry
1645  person->updateDemandElementGeometry(personMap.first, departPos);
1646  // reset person stack label
1647  person->updateDemandElementStackLabel(0);
1648  }
1649 
1650  // sort departPosPersons
1651  std::sort(departPosPersons.begin(), departPosPersons.end());
1652  // iterate over departPosPersons
1653  for (const auto& departPosPerson : departPosPersons) {
1654  // obtain stack position and person
1655  const GNEEdge::StackPosition& personStackPosition = departPosPerson.first;
1656  GNEDemandElement* person = departPosPerson.second;
1657  // if stackedPersons is empty, add a new StackDemandElements
1658  if (stackedPersons.empty()) {
1659  stackedPersons.push_back(GNEEdge::StackDemandElements(personStackPosition, person));
1660  } else if (areStackPositionOverlapped(personStackPosition, stackedPersons.back().getStackPosition())) {
1661  // add new person to last inserted stackDemandElements
1662  stackedPersons[stackedPersons.size() - 1].addDemandElements(person);
1663  } else {
1664  // No overlapping, then add a new StackDemandElements
1665  stackedPersons.push_back(GNEEdge::StackDemandElements(personStackPosition, person));
1666  }
1667  }
1668  // iterate over stackedPersons
1669  for (const auto& person : stackedPersons) {
1670  // only update persons with one or more stack
1671  if (person.getDemandElements().size() > 1) {
1672  // set stack labels
1673  person.getDemandElements().front()->updateDemandElementStackLabel((int)person.getDemandElements().size());
1674  }
1675  }
1676  }
1677 }
1678 
1679 
1680 void
1682  // get lane containers map
1683  const std::map<const GNELane*, std::vector<GNEDemandElement*> > laneContainersMap = getContainersOverEdgeMap();
1684  // iterate over laneContainersMap and obtain a vector with
1685  for (const auto& containerMap : laneContainersMap) {
1686  // declare map for sort containers using their departpos+length position (StackPosition)
1687  std::vector<std::pair<GNEEdge::StackPosition, GNEDemandElement*> > departPosContainers;
1688  // declare vector of stack demand elements
1689  std::vector<GNEEdge::StackDemandElements> stackedContainers;
1690  // iterate over containers
1691  for (const auto& container : containerMap.second) {
1692  // get container's depart pos and length
1693  const double departPos = container->getAttributeDouble(SUMO_ATTR_DEPARTPOS);
1694  // make a stack position using departPos and length
1695  departPosContainers.push_back(std::make_pair(StackPosition(departPos, 1.8), container));
1696  // update depart element geometry
1697  container->updateDemandElementGeometry(containerMap.first, departPos);
1698  // reset container stack label
1699  container->updateDemandElementStackLabel(0);
1700  }
1701 
1702  // sort departPosContainers
1703  std::sort(departPosContainers.begin(), departPosContainers.end());
1704  // iterate over departPosContainers
1705  for (const auto& departPosContainer : departPosContainers) {
1706  // obtain stack position and container
1707  const GNEEdge::StackPosition& containerStackPosition = departPosContainer.first;
1708  GNEDemandElement* container = departPosContainer.second;
1709  // if stackedContainers is empty, add a new StackDemandElements
1710  if (stackedContainers.empty()) {
1711  stackedContainers.push_back(GNEEdge::StackDemandElements(containerStackPosition, container));
1712  } else if (areStackPositionOverlapped(containerStackPosition, stackedContainers.back().getStackPosition())) {
1713  // add new container to last inserted stackDemandElements
1714  stackedContainers[stackedContainers.size() - 1].addDemandElements(container);
1715  } else {
1716  // No overlapping, then add a new StackDemandElements
1717  stackedContainers.push_back(GNEEdge::StackDemandElements(containerStackPosition, container));
1718  }
1719  }
1720  // iterate over stackedContainers
1721  for (const auto& container : stackedContainers) {
1722  // only update containers with one or more stack
1723  if (container.getDemandElements().size() > 1) {
1724  // set stack labels
1725  container.getDemandElements().front()->updateDemandElementStackLabel((int)container.getDemandElements().size());
1726  }
1727  }
1728  }
1729 }
1730 
1731 
1732 bool
1734  // calculate angle between both junction positions
1735  double edgeAngle = RAD2DEG(getFromJunction()->getPositionInView().angleTo2D(getToJunction()->getPositionInView()));
1736  // adjust to 360 degrees
1737  while (edgeAngle < 0) {
1738  edgeAngle += 360;
1739  }
1740  // fmod round towards zero which is not want we want for negative numbers
1741  edgeAngle = fmod(edgeAngle, 360);
1742  // check angle
1743  return edgeAngle >= 0 && edgeAngle < 180;
1744 }
1745 
1746 
1747 bool
1749  // get incoming edges
1750  const auto incomingEdges = getFromJunction()->getGNEIncomingEdges();
1751  // iterate over connections
1752  for (const auto& incomingEdge : incomingEdges) {
1753  for (const auto& connection : incomingEdge->getGNEConnections()) {
1754  if (connection->getEdgeTo() == this) {
1755  return true;
1756  }
1757  }
1758  }
1759  return false;
1760 }
1761 
1762 
1763 bool
1765  return (myGNEConnections.size() > 0);
1766 }
1767 
1768 
1769 GNEEdge*
1771  for (const auto& outgoingEdge : getParentJunctions().back()->getGNEOutgoingEdges()) {
1772  if (outgoingEdge->getToJunction() == getFromJunction()) {
1773  return outgoingEdge;
1774  }
1775  }
1776  return nullptr;
1777 }
1778 
1779 // ===========================================================================
1780 // private
1781 // ===========================================================================
1782 
1783 GNEEdge::StackPosition::StackPosition(const double departPos, const double length) :
1784  pair(departPos, departPos + length) {
1785 }
1786 
1787 
1788 double
1790  return first;
1791 }
1792 
1793 
1794 double
1796  return second;
1797 }
1798 
1799 
1801  pair(stackedPosition, {
1802  demandElement
1803 }) {
1804 }
1805 
1806 
1807 void
1809  second.push_back(demandElement);
1810 }
1811 
1812 
1815  return first;
1816 }
1817 
1818 
1819 const std::vector<GNEDemandElement*>&
1821  return second;
1822 }
1823 
1824 
1825 void
1826 GNEEdge::setAttribute(SumoXMLAttr key, const std::string& value) {
1827  switch (key) {
1828  case SUMO_ATTR_ID:
1829  myNet->getAttributeCarriers()->updateEdgeID(this, value);
1830  // enable save demand elements if there are stops
1831  for (const auto& stop : getChildDemandElements()) {
1832  if (stop->getTagProperty().isVehicleStop()) {
1834  }
1835  }
1836  // also for lanes
1837  for (const auto& lane : myLanes) {
1838  for (const auto& stop : lane->getChildDemandElements()) {
1839  if (stop->getTagProperty().isVehicleStop()) {
1841  }
1842  }
1843  }
1844  break;
1845  case SUMO_ATTR_FROM:
1846  myNet->changeEdgeEndpoints(this, value, getToJunction()->getID());
1847  // update this edge of list of outgoings edges of the old first parent junction
1849  // update first parent junction
1851  // update this edge of list of outgoings edges of the new first parent junction
1853  // update centering boundary and grid
1855  break;
1856  case SUMO_ATTR_TO:
1857  myNet->changeEdgeEndpoints(this, getFromJunction()->getID(), value);
1858  // update this edge of list of incomings edges of the old second parent junction
1860  // update second parent junction
1862  // update this edge of list of incomings edges of the new second parent junction
1864  // update centering boundary and grid
1866  break;
1867  case SUMO_ATTR_NUMLANES:
1868  throw InvalidArgument("GNEEdge::setAttribute (private) called for attr SUMO_ATTR_NUMLANES. This should never happen");
1869  case SUMO_ATTR_PRIORITY:
1870  myNBEdge->myPriority = parse<int>(value);
1871  break;
1872  case SUMO_ATTR_LENGTH:
1873  if (value.empty()) {
1875  } else {
1876  myNBEdge->setLoadedLength(parse<double>(value));
1877  }
1878  break;
1879  case SUMO_ATTR_TYPE:
1880  myNBEdge->myType = value;
1881  break;
1882  case SUMO_ATTR_SHAPE:
1883  // set new geometry
1884  setGeometry(parse<PositionVector>(value), true);
1885  // update centering boundary and grid
1887  break;
1888  case SUMO_ATTR_SPREADTYPE:
1890  break;
1891  case SUMO_ATTR_NAME:
1892  myNBEdge->setStreetName(value);
1893  break;
1894  case SUMO_ATTR_SPEED:
1895  myNBEdge->setSpeed(-1, parse<double>(value));
1896  break;
1897  case SUMO_ATTR_FRICTION:
1898  myNBEdge->setFriction(-1, parse<double>(value));
1899  break;
1900  case SUMO_ATTR_WIDTH:
1901  if (value.empty() || (value == "default")) {
1903  } else {
1904  myNBEdge->setLaneWidth(-1, parse<double>(value));
1905  }
1906  break;
1907  case SUMO_ATTR_ENDOFFSET:
1908  myNBEdge->setEndOffset(-1, parse<double>(value));
1909  break;
1910  case SUMO_ATTR_ALLOW:
1911  break; // no edge value
1912  case SUMO_ATTR_DISALLOW:
1913  break; // no edge value
1914  case SUMO_ATTR_DISTANCE:
1915  if (value.empty()) {
1916  myNBEdge->setDistance(0.0);
1917  } else {
1918  myNBEdge->setDistance(parse<double>(value));
1919  }
1920  break;
1922  myConnectionStatus = value;
1923  if (value == FEATURE_GUESSED) {
1924  WRITE_DEBUG("invalidating (removing) connections of edge '" + getID() + "' due it were guessed");
1927  } else if (value != FEATURE_GUESSED) {
1928  WRITE_DEBUG("declaring connections of edge '" + getID() + "' as loaded (It will not be removed)");
1930  }
1931  break;
1932  case GNE_ATTR_SHAPE_START: {
1933  // get geometry of NBEdge, remove FIRST element with the new value (or with the Junction Source position) and set it back to edge
1934  Position newShapeStart;
1935  if (value == "") {
1936  newShapeStart = getFromJunction()->getNBNode()->getPosition();
1937  } else {
1938  newShapeStart = parse<Position>(value);
1939  }
1940  // set shape start position
1941  setShapeStartPos(newShapeStart);
1942  // update centering boundary and grid
1944  break;
1945  }
1946  case GNE_ATTR_SHAPE_END: {
1947  // get geometry of NBEdge, remove LAST element with the new value (or with the Junction Destination position) and set it back to edge
1948  Position newShapeEnd;
1949  if (value == "") {
1950  newShapeEnd = getToJunction()->getNBNode()->getPosition();
1951  } else {
1952  newShapeEnd = parse<Position>(value);
1953  }
1954  // set shape end position
1955  setShapeEndPos(newShapeEnd);
1956  // update centering boundary and grid
1958  break;
1959  }
1960  case GNE_ATTR_BIDIR:
1961  myNBEdge->setBidi(parse<bool>(value));
1962  break;
1963  case GNE_ATTR_SELECTED:
1964  if (parse<bool>(value)) {
1966  } else {
1968  }
1969  break;
1970  case GNE_ATTR_STOPOFFSET:
1971  if (value.empty()) {
1973  } else {
1974  myNBEdge->myEdgeStopOffset.setOffset(parse<double>(value));
1975  }
1976  break;
1979  break;
1980  case GNE_ATTR_PARAMETERS:
1981  myNBEdge->setParametersStr(value);
1982  break;
1983  default:
1984  throw InvalidArgument(getTagStr() + " doesn't have an attribute of type '" + toString(key) + "'");
1985  }
1986  // get template editor
1988  // check if update template (except for modification status)
1989  if (templateEditor->getEdgeTemplate() && (templateEditor->getEdgeTemplate()->getID() == getID()) &&
1990  (key != GNE_ATTR_MODIFICATION_STATUS)) {
1992  }
1993  // invalidate path calculator
1995 }
1996 
1997 
1998 void
2000  // get start and end points
2001  const Position shapeStart = moveResult.shapeToUpdate.front();
2002  const Position shapeEnd = moveResult.shapeToUpdate.back();
2003  // get innen shape
2004  PositionVector innenShape = moveResult.shapeToUpdate;
2005  innenShape.pop_front();
2006  innenShape.pop_back();
2007  // set shape start
2008  if (std::find(moveResult.geometryPointsToMove.begin(), moveResult.geometryPointsToMove.end(), 0) != moveResult.geometryPointsToMove.end()) {
2009  setShapeStartPos(shapeStart);
2010  }
2011  // set innen geometry
2012  setGeometry(innenShape, true);
2013  // set shape end
2014  if (std::find(moveResult.geometryPointsToMove.begin(), moveResult.geometryPointsToMove.end(), ((int)moveResult.shapeToUpdate.size() - 1)) != moveResult.geometryPointsToMove.end()) {
2015  setShapeEndPos(shapeEnd);
2016  }
2017 }
2018 
2019 
2020 void
2021 GNEEdge::commitMoveShape(const GNEMoveResult& moveResult, GNEUndoList* undoList) {
2022  // make sure that newShape isn't empty
2023  if (moveResult.shapeToUpdate.size() > 0) {
2024  // get innen shape
2025  PositionVector innenShapeToUpdate = moveResult.shapeToUpdate;
2026  innenShapeToUpdate.pop_front();
2027  innenShapeToUpdate.pop_back();
2028  // commit new shape
2029  undoList->begin(this, "moving " + toString(SUMO_ATTR_SHAPE) + " of " + getTagStr());
2030  // update start position
2031  if (std::find(moveResult.geometryPointsToMove.begin(), moveResult.geometryPointsToMove.end(), 0) != moveResult.geometryPointsToMove.end()) {
2033  }
2034  // check if update shape
2035  if (innenShapeToUpdate.size() > 0) {
2036  GNEChange_Attribute::changeAttribute(this, SUMO_ATTR_SHAPE, toString(innenShapeToUpdate), undoList);
2037  }
2038  // update end position
2039  if (std::find(moveResult.geometryPointsToMove.begin(), moveResult.geometryPointsToMove.end(), ((int)moveResult.shapeToUpdate.size() - 1)) != moveResult.geometryPointsToMove.end()) {
2041  }
2042  undoList->end();
2043  }
2044 }
2045 
2046 
2047 void
2048 GNEEdge::setNumLanes(int numLanes, GNEUndoList* undoList) {
2049  // begin undo list
2050  undoList->begin(this, "change number of " + toString(SUMO_TAG_LANE) + "s");
2051  // invalidate logic of source/destination edges
2052  getFromJunction()->setLogicValid(false, undoList);
2053  getToJunction()->setLogicValid(false, undoList);
2054  // disable update geometry (see #6336)
2055  myUpdateGeometry = false;
2056  // remove edge from grid
2058  // save old number of lanes
2059  const int oldNumLanes = (int)myLanes.size();
2060  // get opposite ID
2061  const auto oppositeID = myLanes.back()->getAttribute(GNE_ATTR_OPPOSITE);
2062  if (oppositeID != "") {
2063  // we'll have a different leftmost lane after adding/removing lanes
2065  }
2066  for (int i = oldNumLanes; i < numLanes; i++) {
2067  // since the GNELane does not exist yet, it cannot have yet been referenced so we only pass a zero-pointer
2068  undoList->add(new GNEChange_Lane(this, myNBEdge->getLaneStruct(oldNumLanes - 1)), true);
2069  }
2070  for (int i = (oldNumLanes - 1); i > (numLanes - 1); i--) {
2071  // delete leftmost lane
2072  undoList->add(new GNEChange_Lane(this, myLanes[i], myNBEdge->getLaneStruct(i), false), true);
2073  }
2074  if (oppositeID != "") {
2075  GNEChange_Attribute::changeAttribute(myLanes.back(), GNE_ATTR_OPPOSITE, oppositeID, undoList);
2076  }
2077  // enable updateGeometry again
2078  myUpdateGeometry = true;
2079  // update geometry of entire edge
2080  updateGeometry();
2081  // end undo list
2082  undoList->end();
2083  // update centering boundary (without updating RTREE)
2084  updateCenteringBoundary(false);
2085  // insert edge in grid again
2086  myNet->addGLObjectIntoGrid(this);
2087 }
2088 
2089 
2090 void
2091 GNEEdge::updateFirstParentJunction(const std::string& value) {
2092  std::vector<GNEJunction*> parentJunctions = getParentJunctions();
2093  parentJunctions[0] = myNet->getAttributeCarriers()->retrieveJunction(value);
2094  // replace parent junctions
2095  replaceParentElements(this, parentJunctions);
2096 }
2097 
2098 
2099 void
2100 GNEEdge::updateSecondParentJunction(const std::string& value) {
2101  std::vector<GNEJunction*> parentJunctions = getParentJunctions();
2102  parentJunctions[1] = myNet->getAttributeCarriers()->retrieveJunction(value);
2103  // replace parent junctions
2104  replaceParentElements(this, parentJunctions);
2105 }
2106 
2107 
2108 void
2109 GNEEdge::addLane(GNELane* lane, const NBEdge::Lane& laneAttrs, bool recomputeConnections) {
2110  const int index = lane ? lane->getIndex() : myNBEdge->getNumLanes();
2111  // the laneStruct must be created first to ensure we have some geometry
2112  // unless the connections are fully recomputed, existing indices must be shifted
2113  myNBEdge->addLane(index, true, recomputeConnections, !recomputeConnections);
2114  if (lane) {
2115  // restore a previously deleted lane
2116  myLanes.insert(myLanes.begin() + index, lane);
2117  } else {
2118  // create a new lane by copying leftmost lane
2119  lane = new GNELane(this, index);
2120  myLanes.push_back(lane);
2121  }
2122  lane->incRef("GNEEdge::addLane");
2123  // add in attributeCarriers
2125  // check if lane is selected
2126  if (lane->isAttributeCarrierSelected()) {
2127  lane->selectAttributeCarrier();
2128  }
2129  // we copy all attributes except shape since this is recomputed from edge shape
2130  myNBEdge->setSpeed(lane->getIndex(), laneAttrs.speed);
2131  myNBEdge->setFriction(lane->getIndex(), laneAttrs.friction);
2132  myNBEdge->setPermissions(laneAttrs.permissions, lane->getIndex());
2133  myNBEdge->setPreferredVehicleClass(laneAttrs.preferred, lane->getIndex());
2134  myNBEdge->setEndOffset(lane->getIndex(), laneAttrs.endOffset);
2135  myNBEdge->setLaneWidth(lane->getIndex(), laneAttrs.width);
2136  // update indices
2137  for (int i = 0; i < (int)myLanes.size(); ++i) {
2138  myLanes[i]->setIndex(i);
2139  }
2140  /* while technically correct, this looks ugly
2141  getFromJunction()->invalidateShape();
2142  getToJunction()->invalidateShape();
2143  */
2144  // Remake connections for this edge and all edges that target this lane
2146  // remake connections of all edges of junction source and destination
2147  for (const auto& fromEdge : getFromJunction()->getChildEdges()) {
2148  fromEdge->remakeGNEConnections();
2149  }
2150  // remake connections of all edges of junction source and destination
2151  for (const auto& toEdge : getToJunction()->getChildEdges()) {
2152  toEdge->remakeGNEConnections();
2153  }
2154  // Update geometry with the new lane
2155  updateGeometry();
2156  // update boundary and grid
2158 }
2159 
2160 
2161 void
2162 GNEEdge::removeLane(GNELane* lane, bool recomputeConnections) {
2163  if (myLanes.size() == 0) {
2164  throw ProcessError("Should not remove the last " + toString(SUMO_TAG_LANE) + " from an " + getTagStr());
2165  }
2166  if (lane == nullptr) {
2167  lane = myLanes.back();
2168  }
2169  // check if lane is selected
2170  if (lane->isAttributeCarrierSelected()) {
2171  lane->unselectAttributeCarrier();
2172  }
2173  // before removing, check that lane isn't being inspected
2176  // Delete lane of edge's container
2177  // unless the connections are fully recomputed, existing indices must be shifted
2178  myNBEdge->deleteLane(lane->getIndex(), recomputeConnections, !recomputeConnections);
2179  lane->decRef("GNEEdge::removeLane");
2180  myLanes.erase(myLanes.begin() + lane->getIndex());
2181  // remove from attributeCarriers
2183  // Delete lane if is unreferenced
2184  if (lane->unreferenced()) {
2185  // show extra information for tests
2186  WRITE_DEBUG("Deleting unreferenced " + lane->getTagStr() + " '" + lane->getID() + "' in removeLane()");
2187  delete lane;
2188  }
2189  // update indices
2190  for (int i = 0; i < (int)myLanes.size(); ++i) {
2191  myLanes[i]->setIndex(i);
2192  }
2193  /* while technically correct, this looks ugly
2194  getFromJunction()->invalidateShape();
2195  getToJunction()->invalidateShape();
2196  */
2197  // Remake connections of this edge
2199  // remake connections of all edges of junction source and destination
2200  for (const auto& fromEdge : getFromJunction()->getChildEdges()) {
2201  fromEdge->remakeGNEConnections();
2202  }
2203  // remake connections of all edges of junction source and destination
2204  for (const auto& toEdge : getToJunction()->getChildEdges()) {
2205  toEdge->remakeGNEConnections();
2206  }
2207  // Update element
2208  updateGeometry();
2209  // update boundary and grid
2211 }
2212 
2213 
2214 void
2215 GNEEdge::addConnection(NBEdge::Connection nbCon, bool selectAfterCreation) {
2216  // If a new connection was successfully created
2218  nbCon.keepClear, nbCon.contPos, nbCon.visibility,
2219  nbCon.speed, nbCon.friction, nbCon.customLength, nbCon.customShape, nbCon.uncontrolled)) {
2220  // Create or retrieve existent GNEConnection
2221  GNEConnection* con = retrieveGNEConnection(nbCon.fromLane, nbCon.toEdge, nbCon.toLane);
2222  // add it to GNEConnection container
2223  myGNEConnections.push_back(con);
2224  // Add reference
2225  myGNEConnections.back()->incRef("GNEEdge::addConnection");
2226  // select GNEConnection if needed
2227  if (selectAfterCreation) {
2228  con->selectAttributeCarrier();
2229  }
2230  // update geometry
2231  con->updateGeometry();
2232  }
2233  // actually we only do this to force a redraw
2234  updateGeometry();
2235 }
2236 
2237 
2238 void
2240  // check if is a explicit turnaround
2241  if (nbCon.toEdge == myNBEdge->getTurnDestination()) {
2243  }
2244  // remove NBEdge::connection from NBEdge
2246  // remove their associated GNEConnection
2247  GNEConnection* connection = retrieveGNEConnection(nbCon.fromLane, nbCon.toEdge, nbCon.toLane, false);
2248  if (connection != nullptr) {
2249  connection->decRef("GNEEdge::removeConnection");
2250  myGNEConnections.erase(std::find(myGNEConnections.begin(), myGNEConnections.end(), connection));
2251  // check if connection is selected
2252  if (connection->isAttributeCarrierSelected()) {
2253  connection->unselectAttributeCarrier();
2254  }
2255  // remove it from network
2256  myNet->removeGLObjectFromGrid(connection);
2257  // check if remove it from Attribute Carriers
2258  if (myNet->getAttributeCarriers()->getConnections().count(connection) > 0) {
2260  }
2261  if (connection->unreferenced()) {
2262  // show extra information for tests
2263  WRITE_DEBUG("Deleting unreferenced " + connection->getTagStr() + " '" + connection->getID() + "' in removeConnection()");
2264  // actually we only do this to force a redraw
2265  updateGeometry();
2266  }
2267  }
2268 }
2269 
2270 
2272 GNEEdge::retrieveGNEConnection(int fromLane, NBEdge* to, int toLane, bool createIfNoExist) {
2273  for (const auto& connection : myGNEConnections) {
2274  if ((connection->getFromLaneIndex() == fromLane) && (connection->getEdgeTo()->getNBEdge() == to) && (connection->getToLaneIndex() == toLane)) {
2275  return connection;
2276  }
2277  }
2278  if (createIfNoExist) {
2279  // create new connection. Will be added to the rTree on first geometry computation
2280  GNEConnection* connection = new GNEConnection(myLanes[fromLane], myNet->getAttributeCarriers()->retrieveEdge(to->getID())->getLanes()[toLane]);
2281  // show extra information for tests
2282  WRITE_DEBUG("Created " + connection->getTagStr() + " '" + connection->getID() + "' in retrieveGNEConnection()");
2283  // add it into network
2284  myNet->addGLObjectIntoGrid(connection);
2285  // add it in attributeCarriers
2287  return connection;
2288  } else {
2289  return nullptr;
2290  }
2291 }
2292 
2293 
2294 void
2295 GNEEdge::setEdgeID(const std::string& newID) {
2296  setNetworkElementID(newID);
2297  for (const auto& lane : myLanes) {
2298  lane->setNetworkElementID(getNBEdge()->getLaneID(lane->getIndex()));
2299  }
2300 }
2301 
2302 
2303 bool
2305  for (const auto& lane : myLanes) {
2306  if (lane->isRestricted(vclass)) {
2307  return true;
2308  }
2309  }
2310  return false;
2311 }
2312 
2313 
2314 void
2316  // Remove all crossings that contain this edge in parameter "edges"
2317  for (const auto& crossing : junction->getGNECrossings()) {
2318  if (crossing->checkEdgeBelong(this)) {
2319  myNet->deleteCrossing(crossing, undoList);
2320  }
2321  }
2322 }
2323 
2324 
2325 void
2327  PositionVector modifiedShape = myNBEdge->getGeometry().interpolateZ(
2329  myNBEdge->getToNode()->getPosition().z());
2330  PositionVector innerShape(modifiedShape.begin() + 1, modifiedShape.end() - 1);
2331  setAttribute(SUMO_ATTR_SHAPE, toString(innerShape), undoList);
2332 }
2333 
2334 
2336 GNEEdge::smoothShape(const PositionVector& old, bool forElevation) {
2337  const auto& neteditOptions = OptionsCont::getOptions();
2338  // distinguish 3 cases:
2339  // a) if the edge has exactly 3 or 4 points, use these as control points
2340  // b) if the edge has more than 4 points, use the first 2 and the last 2 as control points
2341  // c) if the edge is straight and both nodes are geometry-like nodes, use geometry of the continuation edges as control points
2342  PositionVector init;
2343 #ifdef DEBUG_SMOOTH_GEOM
2344  if (DEBUGCOND(this)) std::cout << getID()
2345  << " forElevation=" << forElevation
2346  << " fromGeometryLike=" << myNBEdge->getFromNode()->geometryLike()
2347  << " toGeometryLike=" << myNBEdge->getToNode()->geometryLike()
2348  << " smoothShape old=" << old << "\n";
2349 #endif
2350  if (old.size() == 3 || old.size() == 4) {
2351  init = old;
2352  } else if (old.size() > 4 && !forElevation) {
2353  // for elevation, the initial segments are not useful
2354  init.push_back(old[0]);
2355  init.push_back(old[1]);
2356  init.push_back(old[-2]);
2357  init.push_back(old[-1]);
2358  } else if (myNBEdge->getFromNode()->geometryLike() && myNBEdge->getToNode()->geometryLike()) {
2359  PositionVector begShape;
2360  PositionVector endShape;
2361  const EdgeVector& incoming = myNBEdge->getFromNode()->getIncomingEdges();
2362  const EdgeVector& outgoing = myNBEdge->getToNode()->getOutgoingEdges();
2363  if (incoming.size() == 1) {
2364  begShape = incoming[0]->getGeometry();
2365  } else {
2366  assert(incoming.size() == 2);
2367  begShape = myNBEdge->isTurningDirectionAt(incoming[0]) ? incoming[1]->getGeometry() : incoming[0]->getGeometry();
2368  }
2369  if (outgoing.size() == 1) {
2370  endShape = outgoing[0]->getGeometry();
2371  } else {
2372  assert(outgoing.size() == 2);
2373  endShape = myNBEdge->isTurningDirectionAt(outgoing[0]) ? outgoing[1]->getGeometry() : outgoing[0]->getGeometry();
2374  }
2375  const double dist = MIN2(old.length2D(), MAX2(old.length2D() / 8, fabs(old[0].z() - old[-1].z()) * OptionsCont::getOptions().getFloat("geometry.max-grade") / 3));
2376  if (forElevation) {
2377  // initialize control point elevation for smooth continuation
2378  init.push_back(old[0]);
2379  init.push_back(old.positionAtOffset2D(dist));
2380  init.push_back(old.positionAtOffset2D(old.length2D() - dist));
2381  init.push_back(old[-1]);
2382  double begZ = begShape.positionAtOffset2D(MAX2(0.0, begShape.length2D() - dist)).z();
2383  double endZ = endShape.positionAtOffset2D(MIN2(begShape.length2D(), dist)).z();
2384  // continue incline
2385  init[1].setz(2 * init[0].z() - begZ);
2386  init[2].setz(2 * init[-1].z() - endZ);
2387  } else {
2388  bool ok = true;
2389  const double straightThresh = DEG2RAD(neteditOptions.getFloat("opendrive-output.straight-threshold"));
2390  init = NBNode::bezierControlPoints(begShape, endShape, false, dist, dist, ok, nullptr, straightThresh);
2391  }
2392 #ifdef DEBUG_SMOOTH_GEOM
2393  if (DEBUGCOND(this)) {
2394  std::cout << " begShape=" << begShape << " endShape=" << endShape << " forElevation=" << forElevation << " dist=" << dist << " ok=" << ok << " init=" << init << "\n";
2395  }
2396 #endif
2397  }
2398  if (init.size() == 0) {
2399  return PositionVector::EMPTY;
2400  } else {
2401  const int numPoints = MAX2(neteditOptions.getInt("junctions.internal-link-detail"),
2402  int(old.length2D() / neteditOptions.getFloat("opendrive.curve-resolution")));
2403  return init.bezier(numPoints);
2404  }
2405 }
2406 
2407 
2408 void
2410  PositionVector modifiedShape = smoothShape(myNBEdge->getGeometry(), false);
2411  if (modifiedShape.size() < 2) {
2412  WRITE_WARNINGF(TL("Could not compute smooth shape for edge '%'"), getID());
2413  } else {
2414  PositionVector innerShape(modifiedShape.begin() + 1, modifiedShape.end() - 1);
2415  setAttribute(SUMO_ATTR_SHAPE, toString(innerShape), undoList);
2416  }
2417 }
2418 
2419 
2420 void
2422  PositionVector elevationBase;
2423  for (const Position& pos : myNBEdge->getGeometry()) {
2424  if (elevationBase.size() == 0 || elevationBase[-1].z() != pos.z()) {
2425  elevationBase.push_back(pos);
2426  }
2427  }
2428  PositionVector elevation = smoothShape(elevationBase, true);
2429  if (elevation.size() <= 2) {
2430  WRITE_WARNINGF(TL("Could not compute smooth elevation for edge '%'"), getID());
2431  } else {
2432  PositionVector modifiedShape = myNBEdge->getGeometry();
2433  if (modifiedShape.size() < 5) {
2434  modifiedShape = modifiedShape.resample(OptionsCont::getOptions().getFloat("opendrive.curve-resolution"), false);
2435  }
2436  const double scale = elevation.length2D() / modifiedShape.length2D();
2437  //std::cout << " elevation=" << elevation << "\n mod1=" << modifiedShape << " scale=" << scale << "\n";
2438  double seen = 0;
2439  for (int i = 1; i < (int)modifiedShape.size(); ++i) {
2440  seen += modifiedShape[i - 1].distanceTo2D(modifiedShape[i]);
2441  modifiedShape[i].setz(elevation.positionAtOffset2D(seen * scale).z());
2442  }
2443  //std::cout << " mod2=" << modifiedShape << "\n";
2444  PositionVector innerShape(modifiedShape.begin() + 1, modifiedShape.end() - 1);
2445  setAttribute(SUMO_ATTR_SHAPE, toString(innerShape), undoList);
2446  }
2447 }
2448 
2449 
2450 void
2452  // remove start position and add it the new position
2454  geom.pop_front();
2455  geom.push_front(pos);
2456  // restore modified shape
2457  setGeometry(geom, false);
2458 }
2459 
2460 
2461 void
2463  // remove end position and add it the new position
2465  geom.pop_back();
2466  geom.push_back(pos);
2467  // restore modified shape
2468  setGeometry(geom, false);
2469 }
2470 
2471 
2472 const std::map<const GNELane*, std::vector<GNEDemandElement*> >
2474  // declare vehicles over edge vector
2475  std::vector<GNEDemandElement*> vehiclesOverEdge;
2476  // declare solution map
2477  std::map<const GNELane*, std::vector<GNEDemandElement*> > vehiclesOverEdgeMap;
2478  // declare a set of vehicles (to avoid duplicates)
2479  std::set<std::pair<double, GNEDemandElement*> > vehicles;
2480  // first obtain all vehicles of this edge
2481  for (const auto& edgeChild : getChildDemandElements()) {
2482  if (((edgeChild->getTagProperty().getTag() == SUMO_TAG_TRIP) || (edgeChild->getTagProperty().getTag() == SUMO_TAG_FLOW)) &&
2483  (edgeChild->getParentEdges().front() == this)) {
2484  vehicles.insert(std::make_pair(edgeChild->getAttributeDouble(SUMO_ATTR_DEPART), edgeChild));
2485  vehicles.insert(std::make_pair(edgeChild->getAttributeDouble(SUMO_ATTR_DEPART), edgeChild));
2486  } else if ((edgeChild->getTagProperty().getTag() == SUMO_TAG_ROUTE) && (edgeChild->getParentEdges().front() == this)) {
2487  for (const auto& routeChild : edgeChild->getChildDemandElements()) {
2488  if (routeChild->getTagProperty().vehicleRoute()) {
2489  vehicles.insert(std::make_pair(routeChild->getAttributeDouble(SUMO_ATTR_DEPART), routeChild));
2490  }
2491  }
2492  } else if ((edgeChild->getTagProperty().getTag() == GNE_TAG_ROUTE_EMBEDDED) && (edgeChild->getParentEdges().front() == this)) {
2493  vehicles.insert(std::make_pair(edgeChild->getParentDemandElements().front()->getAttributeDouble(SUMO_ATTR_DEPART), edgeChild->getParentDemandElements().front()));
2494  }
2495  }
2496  // reserve
2497  vehiclesOverEdge.reserve(vehicles.size());
2498  // iterate over vehicles
2499  for (const auto& vehicle : vehicles) {
2500  // add it over vehiclesOverEdge;
2501  vehiclesOverEdge.push_back(vehicle.second);
2502  }
2503  // now split vehicles by lanes
2504  for (const auto& vehicle : vehiclesOverEdge) {
2505  const GNELane* vehicleLane = vehicle->getFirstPathLane();
2506  if (vehicleLane) {
2507  vehiclesOverEdgeMap[vehicleLane].push_back(vehicle);
2508  }
2509  }
2510  return vehiclesOverEdgeMap;
2511 }
2512 
2513 
2514 const std::map<const GNELane*, std::vector<GNEDemandElement*> >
2516  // declare persons over edge vector
2517  std::vector<GNEDemandElement*> personsOverEdge;
2518  // declare solution map
2519  std::map<const GNELane*, std::vector<GNEDemandElement*> > personsOverEdgeMap;
2520  // declare a set of persons (to avoid duplicates)
2521  std::set<std::pair<double, GNEDemandElement*> > persons;
2522  // first obtain all persons of this edge
2523  for (const auto& edgeChild : getChildDemandElements()) {
2524  if (edgeChild->getTagProperty().isPlanPerson()) {
2525  persons.insert(std::make_pair(edgeChild->getParentDemandElements().front()->getAttributeDouble(SUMO_ATTR_DEPARTPOS), edgeChild->getParentDemandElements().front()));
2526  }
2527  }
2528  // reserve
2529  personsOverEdge.reserve(persons.size());
2530  // iterate over persons
2531  for (const auto& person : persons) {
2532  // add it over personsOverEdge;
2533  personsOverEdge.push_back(person.second);
2534  }
2535  // now split persons by lanes
2536  for (const auto& person : personsOverEdge) {
2537  const GNELane* personLane = person->getFirstPathLane();
2538  if (personLane) {
2539  personsOverEdgeMap[personLane].push_back(person);
2540  }
2541  }
2542  return personsOverEdgeMap;
2543 }
2544 
2545 
2546 
2547 const std::map<const GNELane*, std::vector<GNEDemandElement*> >
2549  // declare containers over edge vector
2550  std::vector<GNEDemandElement*> containersOverEdge;
2551  // declare solution map
2552  std::map<const GNELane*, std::vector<GNEDemandElement*> > containersOverEdgeMap;
2553  // declare a set of containers (to avoid duplicates)
2554  std::set<std::pair<double, GNEDemandElement*> > containers;
2555  // first obtain all containers of this edge
2556  for (const auto& edgeChild : getChildDemandElements()) {
2557  if (edgeChild->getTagProperty().isPlanContainer()) {
2558  containers.insert(std::make_pair(edgeChild->getParentDemandElements().front()->getAttributeDouble(SUMO_ATTR_DEPARTPOS), edgeChild->getParentDemandElements().front()));
2559  }
2560  }
2561  // reserve
2562  containersOverEdge.reserve(containers.size());
2563  // iterate over containers
2564  for (const auto& container : containers) {
2565  // add it over containersOverEdge;
2566  containersOverEdge.push_back(container.second);
2567  }
2568  // now split containers by lanes
2569  for (const auto& container : containersOverEdge) {
2570  const GNELane* containerLane = container->getFirstPathLane();
2571  if (containerLane) {
2572  containersOverEdgeMap[containerLane].push_back(container);
2573  }
2574  }
2575  return containersOverEdgeMap;
2576 }
2577 
2578 
2579 void
2581  // first check conditions
2583  // check if draw geometry points
2584  const bool bigGeometryPoints = drawBigGeometryPoints();
2585  // Obtain exaggeration of the draw
2586  const double exaggeration = getExaggeration(s);
2587  // get geometry point radius
2588  const double geometryPointRadius = getGeometryPointRadius();
2589  // obtain geometry point color
2590  RGBColor geometryPointColor = s.junctionColorer.getSchemes()[0].getColor(2);
2591  if (drawUsingSelectColor() && s.laneColorer.getActive() != 1) {
2592  // override with special colors (unless the color scheme is based on selection)
2593  geometryPointColor = s.colorSettings.selectedEdgeColor.changedBrightness(-20);
2594  }
2595  // draw geometry points except initial and final
2596  for (int i = 1; i < (int)myNBEdge->getGeometry().size() - 1; i++) {
2597  // obtain geometry point
2598  const auto geometryPointPos = myNBEdge->getGeometry()[i];
2599  // push geometry point drawing matrix
2601  // set color
2602  GLHelper::setColor(geometryPointColor);
2603  // move geometry point geometryPointPos
2604  glTranslated(geometryPointPos.x(), geometryPointPos.y(), bigGeometryPoints ? GLO_GEOMETRYPOINT : GLO_LANE + 1);
2605  // draw filled circle (resolution of drawn circle depending of the zoom, to improve smoothness)
2606  GLHelper::drawFilledCircleDetailled(d, geometryPointRadius);
2607  // draw elevation or special symbols (Start, End and Block)
2609  // Translate to top
2610  glTranslated(0, 0, 0.2);
2611  // draw Z value
2612  GLHelper::drawText(toString(geometryPointPos.z()), Position(), 0, s.edgeValue.scaledSize(s.scale) / 2, s.edgeValue.color);
2613  }
2614  // pop geometry point drawing matrix
2616  }
2617  // draw start and end points
2618  if (bigGeometryPoints) {
2619  drawStartGeometryPoint(s, d, geometryPointRadius, exaggeration);
2620  drawEndGeometryPoint(s, d, geometryPointRadius, exaggeration);
2621  }
2622  // draw dotted contour geometry points
2624  exaggeration, s.dottedContourSettings.segmentWidthSmall);
2625  }
2626 }
2627 
2628 
2629 void
2631  const double geometryPointRadius, const double exaggeration) const {
2632  // check detail level
2634  // get first geometry point
2635  const auto& startGeometryPointPos = myNBEdge->getGeometry().front();
2636  // get flags
2637  const bool startPosEdited = (startGeometryPointPos != getParentJunctions().front()->getPositionInView());
2639  // check drawing conditions
2640  if (startPosEdited || forceDraw) {
2641  // calculate angle betwen first and second geometry point
2642  const double angle = RAD2DEG(startGeometryPointPos.angleTo2D(myNBEdge->getGeometry()[1])) * -1;
2643  // get selected geometry points
2644  const auto selectedGeometryPoints = gViewObjectsHandler.getGeometryPoints(this);
2645  // override with special colors (unless the color scheme is based on selection)
2646  if (drawUsingSelectColor() && s.laneColorer.getActive() != 1) {
2648  } else {
2649  GLHelper::setColor(s.junctionColorer.getSchemes()[0].getColor(2));
2650  }
2651  // push drawing matrix
2653  // move to point position
2654  glTranslated(startGeometryPointPos.x(), startGeometryPointPos.y(), GLO_GEOMETRYPOINT);
2655  // resolution of drawn circle depending of detail
2656  GLHelper::drawFilledCircleDetailled(d, geometryPointRadius, angle + 90, angle + 270);
2657  // pop drawing matrix
2659  // draw a "s" over last point depending of detail level
2661  // push drawing matrix
2663  // move top
2664  glTranslated(0, 0, GLO_GEOMETRYPOINT + 0.1);
2665  // draw S
2666  GLHelper::drawText("S", startGeometryPointPos, 0, geometryPointRadius, RGBColor(0, 50, 255));
2667  // pop drawing matrix
2669  // check if draw line between junctions
2670  if ((selectedGeometryPoints.size() > 0) && (selectedGeometryPoints.front() == 0)) {
2671  // set base color
2673  // push drawing matrix
2675  // draw line between geometry point and from junction
2676  const PositionVector lineA = {startGeometryPointPos, getFromJunction()->getNBNode()->getPosition()};
2677  GLHelper::drawBoxLine(lineA[1], RAD2DEG(lineA[0].angleTo2D(lineA[1])) - 90, lineA[0].distanceTo2D(lineA[1]), .1);
2678  // draw line between begin point of last lane shape and the first edge shape point
2679  const PositionVector lineB = {startGeometryPointPos, myNBEdge->getLanes().back().shape.front()};
2680  GLHelper::drawBoxLine(lineB[1], RAD2DEG(lineB[0].angleTo2D(lineB[1])) - 90, lineB[0].distanceTo2D(lineB[1]), .1);
2681  // pop drawing matrix
2683  }
2684  }
2685  // draw dotted contour geometry points
2687  geometryPointRadius, exaggeration);
2688  }
2689  }
2690 }
2691 
2692 
2693 void
2695  const double geometryPointRadius, const double exaggeration) const {
2696  // check detail level
2698  // get first geometry point
2699  const auto& geometryPointPos = myNBEdge->getGeometry().back();
2700  // get flags
2701  const bool endPosEdited = (geometryPointPos != getParentJunctions().back()->getPositionInView());
2703  // check drawing conditions
2704  if (endPosEdited || forceDraw) {
2705  // calculate angle last and previous geometry point
2706  const double angle = RAD2DEG(geometryPointPos.angleTo2D(myNBEdge->getGeometry()[-2])) * -1;
2707  // get selected geometry points
2708  const auto selectedGeometryPoints = gViewObjectsHandler.getGeometryPoints(this);
2709  // override with special colors (unless the color scheme is based on selection)
2710  if (drawUsingSelectColor() && s.laneColorer.getActive() != 1) {
2712  } else {
2713  GLHelper::setColor(s.junctionColorer.getSchemes()[0].getColor(2));
2714  }
2715  // push drawing matrix
2717  // move to point position
2718  glTranslated(geometryPointPos.x(), geometryPointPos.y(), GLO_GEOMETRYPOINT);
2719  // resolution of drawn circle depending of detail
2720  GLHelper::drawFilledCircleDetailled(d, geometryPointRadius, angle + 90, angle + 270);
2721  // pop drawing matrix
2723  // draw a "s" over last point depending of detail level
2725  // push drawing matrix
2727  // move top
2728  glTranslated(0, 0, GLO_GEOMETRYPOINT + 0.1);
2729  // draw S
2730  GLHelper::drawText("E", geometryPointPos, 0, geometryPointRadius, RGBColor(0, 50, 255));
2731  // pop drawing matrix
2733  // check if draw line between junctions
2734  if ((selectedGeometryPoints.size() > 0) && (selectedGeometryPoints.back() == ((int)myNBEdge->getGeometry().size() - 1))) {
2735  // set base color
2737  // push drawing matrix
2739  // draw line between geometry point and from junction
2740  const PositionVector lineA = {geometryPointPos, getToJunction()->getNBNode()->getPosition()};
2741  GLHelper::drawBoxLine(lineA[1], RAD2DEG(lineA[0].angleTo2D(lineA[1])) - 90, lineA[0].distanceTo2D(lineA[1]), .1);
2742  // draw line between begin point of last lane shape and the first edge shape point
2743  const PositionVector lineB = {geometryPointPos, myNBEdge->getLanes().back().shape.back()};
2744  GLHelper::drawBoxLine(lineB[1], RAD2DEG(lineB[0].angleTo2D(lineB[1])) - 90, lineB[0].distanceTo2D(lineB[1]), .1);
2745  // pop drawing matrix
2747  }
2748  }
2749  // draw dotted contour geometry points
2751  geometryPointRadius, exaggeration);
2752  }
2753  }
2754 }
2755 
2756 
2757 void
2759  // draw the name and/or the street name
2760  const bool drawStreetName = s.streetName.show(this) && (myNBEdge->getStreetName() != "");
2761  const bool spreadSuperposed = s.spreadSuperposed && myNBEdge->getBidiEdge() != nullptr;
2762  // check conditions
2763  if (s.edgeName.show(this) || drawStreetName || s.edgeValue.show(this)) {
2764  // get first and last lanes
2765  const GNELane* firstLane = myLanes[0];
2766  const GNELane* lastLane = myLanes[myLanes.size() - 1];
2767  // calculate draw position
2768  Position drawPosition = firstLane->getLaneShape().positionAtOffset(firstLane->getLaneShape().length() / (double) 2.);
2769  drawPosition.add(lastLane->getLaneShape().positionAtOffset(lastLane->getLaneShape().length() / (double) 2.));
2770  drawPosition.mul(.5);
2771  if (spreadSuperposed) {
2772  // move name to the right of the edge and towards its beginning
2773  const double dist = 0.6 * s.edgeName.scaledSize(s.scale);
2774  const double shiftA = firstLane->getLaneShape().rotationAtOffset(firstLane->getLaneShape().length() / (double) 2.) - DEG2RAD(135);
2775  const Position shift(dist * cos(shiftA), dist * sin(shiftA));
2776  drawPosition.add(shift);
2777  }
2778  // calculate drawing angle
2779  double drawAngle = firstLane->getLaneShape().rotationDegreeAtOffset(firstLane->getLaneShape().length() / (double) 2.);
2780  drawAngle += 90;
2781  // avoid draw inverted text
2782  if (drawAngle > 90 && drawAngle < 270) {
2783  drawAngle -= 180;
2784  }
2785  // draw edge name
2786  if (s.edgeName.show(this)) {
2787  drawName(drawPosition, s.scale, s.edgeName, drawAngle);
2788  }
2789  // draw street name
2790  if (drawStreetName) {
2791  GLHelper::drawTextSettings(s.streetName, myNBEdge->getStreetName(), drawPosition, s.scale, drawAngle);
2792  }
2793  // draw edge values
2794  if (s.edgeValue.show(this)) {
2795  // get current scheme
2796  const int activeScheme = s.laneColorer.getActive();
2797  // calculate value depending of active scheme
2798  std::string value;
2799  if (activeScheme == 12) {
2800  // edge param, could be non-numerical
2801  value = getNBEdge()->getParameter(s.edgeParam, "");
2802  } else if (activeScheme == 13) {
2803  // lane param, could be non-numerical
2804  value = getNBEdge()->getLaneStruct(lastLane->getIndex()).getParameter(s.laneParam, "");
2805  } else {
2806  // use numerical value value of leftmost lane to hopefully avoid sidewalks, bikelanes etc
2807  const double doubleValue = lastLane->getColorValue(s, activeScheme);
2808  const RGBColor color = s.laneColorer.getScheme().getColor(doubleValue);
2809  value = color.alpha() == 0 ? "" : toString(doubleValue);
2810  }
2811  // check if value is empty
2812  if (value != "") {
2813  GLHelper::drawTextSettings(s.edgeValue, value, drawPosition, s.scale, drawAngle);
2814  }
2815  }
2816  }
2817 }
2818 
2819 
2820 void
2822  // draw geometry only if we'rent in drawForObjectUnderCursor mode
2824  // Push stopOffset matrix
2826  // translate to front (note: Special case)
2827  if (myNet->getViewNet()->getFrontAttributeCarrier() == this) {
2828  glTranslated(0, 0, GLO_FRONTELEMENT);
2829  } else {
2831  }
2833  for (const auto& lane : getLanes()) {
2834  lane->drawLaneStopOffset(s);
2835  }
2836  }
2837  // Push stopOffset matrix
2839  }
2840 }
2841 
2842 
2843 void
2845  // draw child additional
2846  for (const auto& additional : getChildAdditionals()) {
2847  additional->drawGL(s);
2848  }
2849  // draw person stops
2851  for (const auto& stopEdge : getChildDemandElements()) {
2852  if ((stopEdge->getTagProperty().getTag() == GNE_TAG_STOPPERSON_EDGE) || (stopEdge->getTagProperty().getTag() == GNE_TAG_STOPCONTAINER_EDGE)) {
2853  stopEdge->drawGL(s);
2854  }
2855  }
2856  }
2857  // draw vehicles
2858  const std::map<const GNELane*, std::vector<GNEDemandElement*> > vehiclesMap = getVehiclesOverEdgeMap();
2859  for (const auto& vehicleMap : vehiclesMap) {
2860  for (const auto& vehicle : vehicleMap.second) {
2861  vehicle->drawGL(s);
2862  }
2863  }
2864  // draw TAZ elements
2865  drawTAZElements(s);
2866 }
2867 
2868 
2869 void
2871  // if we're selecting using a boundary, first don't calculate contour bt check if edge boundary is within selection boundary
2873  // simply add object in ViewObjectsHandler with full boundary
2874  gViewObjectsHandler.addElementUnderCursor(this, false, true);
2875  } else {
2876  // get geometry point radius
2877  const auto geometryPointRadius = getGeometryPointRadius();
2878  // check if edit extrems
2879  const bool forceDrawExtrems = myNet->getViewNet()->getViewParent()->getMoveFrame()->getNetworkModeOptions()->getForceDrawGeometryPoints();
2880  const bool firstExtrem = forceDrawExtrems || (myNBEdge->getGeometry().front() != getParentJunctions().front()->getPositionInView());
2881  const bool lastExtrem = forceDrawExtrems || (myNBEdge->getGeometry().back() != getParentJunctions().back()->getPositionInView());
2882  // check if we're in move mode
2884  // calculate contour
2885  myNetworkElementContour.calculateContourEdge(s, d, this, this, true, true);
2886  // calculate edge geometry points
2887  myNetworkElementContour.calculateContourEdgeGeometryPoints(s, d, this, geometryPointRadius, moveMode, firstExtrem, lastExtrem);
2888  }
2889 }
2890 
2891 
2892 void
2894  // first check if draw TAZ Elements is enabled
2896  std::vector<GNEAdditional*> TAZSourceSinks;
2897  // get all TAZ source/sinks vinculated with this edge
2898  for (const auto& additional : getChildAdditionals()) {
2899  if ((additional->getTagProperty().getTag() == SUMO_TAG_TAZSOURCE) ||
2900  (additional->getTagProperty().getTag() == SUMO_TAG_TAZSINK)) {
2901  TAZSourceSinks.push_back(additional);
2902  }
2903  }
2904  if (TAZSourceSinks.size() > 0) {
2905  // check if TAZ Source/sink is selected
2906  bool selected = false;
2907  for (const auto& TAZSourceSink : TAZSourceSinks) {
2908  if (TAZSourceSink->isAttributeCarrierSelected()) {
2909  selected = true;
2910  }
2911  }
2912  // iterate over lanes
2913  for (const auto& lane : myLanes) {
2914  // Push layer matrix
2916  // translate to front (note: Special case)
2917  if (myNet->getViewNet()->getFrontAttributeCarrier() == this) {
2918  glTranslated(0, 0, GLO_FRONTELEMENT);
2919  } else if (lane->getLaneShape().length2D() <= (s.neteditSizeSettings.junctionBubbleRadius * 2)) {
2921  } else {
2923  }
2924  // move to front
2925  glTranslated(0, 0, 0.1);
2926  // set color
2927  if (selected) {
2929  } else {
2931  }
2932  // draw as box lines
2934  lane->getDrawingConstants()->getDrawingWidth());
2935  // Pop layer matrix
2937  }
2938  /*
2939  // check if curently we're inspecting a TAZ Source/Sink
2940  for (const auto& TAZSourceSink : TAZSourceSinks) {
2941  if (myNet->getViewNet()->isAttributeCarrierInspected(TAZSourceSink)) {
2942  drawDottedContourEdge(s, GUIDottedGeometry::DottedContourType::INSPECT, this, true, true);
2943  } else if (TAZSourceSink == frontAC) {
2944  drawDottedContourEdge(s, GUIDottedGeometry::DottedContourType::FRONT, this, true, true);
2945  }
2946  }
2947  */
2948  }
2949  }
2950 }
2951 
2952 
2953 void
2955  // avoid draw for railways
2956  if ((d <= GUIVisualizationSettings::Detail::LaneDetails) && !myLanes.front()->getDrawingConstants()->drawAsRailway() &&
2958  // push draw matrix
2960  // translate to front depending of big points
2961  if (drawBigGeometryPoints()) {
2962  glTranslated(0, 0, GLO_GEOMETRYPOINT - 1);
2963  } else {
2964  glTranslated(0, 0, GLO_EDGE);
2965  }
2966  // obtain color
2967  RGBColor geometryPointColor = s.junctionColorer.getSchemes()[0].getColor(2);
2968  if (drawUsingSelectColor() && s.laneColorer.getActive() != 1) {
2969  // override with special colors (unless the color scheme is based on selection)
2970  geometryPointColor = s.colorSettings.selectedEdgeColor.changedBrightness(-20);
2971  }
2972  // set color
2973  GLHelper::setColor(geometryPointColor);
2974  // iterate over NBEdge geometry
2975  for (int i = 1; i < (int)myNBEdge->getGeometry().size(); i++) {
2976  // calculate line between previous and current geometry point
2977  PositionVector line = {myNBEdge->getGeometry()[i - 1], myNBEdge->getGeometry()[i]};
2978  line.move2side(0.2);
2979  // draw box line
2980  GLHelper::drawBoxLine(line[1], RAD2DEG(line[0].angleTo2D(line[1])) - 90, line[0].distanceTo2D(line[1]), .1);
2981  }
2982  // pop draw matrix
2984  }
2985 }
2986 
2987 
2988 bool
2990  // get edit modes
2991  const auto& editModes = myNet->getViewNet()->getEditModes();
2992  // continue depending of conditions
2993  if (!editModes.isCurrentSupermodeNetwork()) {
2994  return false;
2995  } else if (editModes.networkEditMode == NetworkEditMode::NETWORK_MOVE) {
2996  return true;
2997  } else if ((editModes.networkEditMode == NetworkEditMode::NETWORK_DELETE) &&
2999  return true;
3000  } else {
3001  return false;
3002  }
3003 }
3004 
3005 
3006 bool
3008  if ((vehicleA.beginPosition() == vehicleB.beginPosition()) && (vehicleA.endPosition() == vehicleB.endPosition())) {
3009  return true;
3010  } else if ((vehicleA.beginPosition() < vehicleB.beginPosition()) && (vehicleA.endPosition() > vehicleB.endPosition())) {
3011  return true;
3012  } else if ((vehicleA.beginPosition() < vehicleB.beginPosition()) && (vehicleA.endPosition() > vehicleB.beginPosition())) {
3013  return true;
3014  } else if ((vehicleA.beginPosition() < vehicleB.endPosition()) && (vehicleA.endPosition() > vehicleB.endPosition())) {
3015  return true;
3016  } else {
3017  return false;
3018  }
3019 }
3020 
3021 
3023 GNEEdge::processMoveFromJunctionSelected(const PositionVector originalShape, const Position mousePosition, const double snapRadius) {
3024  // calculate squared snapRadius
3025  const double squaredSnapRadius = (snapRadius * snapRadius);
3026  // declare shape to move
3027  PositionVector shapeToMove = originalShape;
3028  // obtain nearest index
3029  const int nearestIndex = originalShape.indexOfClosest(mousePosition);
3030  // obtain nearest position
3031  const Position nearestPosition = originalShape.positionAtOffset2D(originalShape.nearest_offset_to_point2D(mousePosition));
3032  // generate indexes
3033  std::vector<int> indexes;
3034  // check conditions
3035  if (nearestIndex == -1) {
3036  return nullptr;
3037  } else if (nearestPosition == Position::INVALID) {
3038  // special case for extremes
3039  if (mousePosition.distanceSquaredTo2D(shapeToMove[nearestIndex]) <= squaredSnapRadius) {
3040  for (int i = 1; i <= nearestIndex; i++) {
3041  indexes.push_back(i);
3042  }
3043  // move extrem without creating new geometry point
3044  return new GNEMoveOperation(this, originalShape, indexes, shapeToMove, indexes);
3045  } else {
3046  return nullptr;
3047  }
3048  } else if (nearestPosition.distanceSquaredTo2D(shapeToMove[nearestIndex]) <= squaredSnapRadius) {
3049  for (int i = 1; i <= nearestIndex; i++) {
3050  indexes.push_back(i);
3051  }
3052  // move geometry point without creating new geometry point
3053  return new GNEMoveOperation(this, originalShape, indexes, shapeToMove, indexes);
3054  } else {
3055  // create new geometry point and keep new index (if we clicked near of shape)
3056  const int newIndex = shapeToMove.insertAtClosest(nearestPosition, true);
3057  for (int i = 1; i <= newIndex; i++) {
3058  indexes.push_back(i);
3059  }
3060  // move after setting new geometry point in shapeToMove
3061  return new GNEMoveOperation(this, originalShape, indexes, shapeToMove, indexes);
3062  }
3063 }
3064 
3065 
3067 GNEEdge::processMoveToJunctionSelected(const PositionVector originalShape, const Position mousePosition, const double snapRadius) {
3068  // calculate squared snapRadius
3069  const double squaredSnapRadius = (snapRadius * snapRadius);
3070  // declare shape to move
3071  PositionVector shapeToMove = originalShape;
3072  // obtain nearest index
3073  const int nearestIndex = originalShape.indexOfClosest(mousePosition);
3074  // obtain nearest position
3075  const Position nearestPosition = originalShape.positionAtOffset2D(originalShape.nearest_offset_to_point2D(mousePosition));
3076  // generate indexes
3077  std::vector<int> indexes;
3078  // check conditions
3079  if (nearestIndex == -1) {
3080  return nullptr;
3081  } else if (nearestPosition == Position::INVALID) {
3082  // special case for extremes
3083  if (mousePosition.distanceSquaredTo2D(shapeToMove[nearestIndex]) <= squaredSnapRadius) {
3084  for (int i = nearestIndex; i < ((int)originalShape.size() - 1); i++) {
3085  indexes.push_back(i);
3086  }
3087  // move extrem without creating new geometry point
3088  return new GNEMoveOperation(this, originalShape, indexes, shapeToMove, indexes);
3089  } else {
3090  return nullptr;
3091  }
3092  } else if (nearestPosition.distanceSquaredTo2D(shapeToMove[nearestIndex]) <= squaredSnapRadius) {
3093  for (int i = nearestIndex; i < ((int)originalShape.size() - 1); i++) {
3094  indexes.push_back(i);
3095  }
3096  // move geometry point without creating new geometry point
3097  return new GNEMoveOperation(this, originalShape, indexes, shapeToMove, indexes);
3098  } else {
3099  // create new geometry point and keep new index (if we clicked near of shape)
3100  const int newIndex = shapeToMove.insertAtClosest(nearestPosition, true);
3101  for (int i = newIndex; i < ((int)originalShape.size() - 1); i++) {
3102  indexes.push_back(i);
3103  }
3104  // move after setting new geometry point in shapeToMove
3105  return new GNEMoveOperation(this, originalShape, indexes, shapeToMove, indexes);
3106  }
3107 }
3108 
3109 
3112  std::vector<int> geometryPointsToMove;
3113  for (int i = 0; i < (int)myNBEdge->getGeometry().size(); i++) {
3114  geometryPointsToMove.push_back(i);
3115  }
3116  // move entire shape (including extremes)
3117  return new GNEMoveOperation(this, myNBEdge->getGeometry(), geometryPointsToMove, myNBEdge->getGeometry(), geometryPointsToMove);
3118 }
3119 
3120 
3122 GNEEdge::processNoneJunctionSelected(const double snapRadius) {
3123  // get move multiple element values
3124  const auto& moveMultipleElementValues = myNet->getViewNet()->getMoveMultipleElementValues();
3125  // declare shape to move
3126  PositionVector shapeToMove = myNBEdge->getGeometry();
3127  // first check if kept offset is larger than geometry
3128  if (shapeToMove.length2D() < moveMultipleElementValues.getEdgeOffset()) {
3129  return nullptr;
3130  }
3131  // declare offset
3132  double offset = 0;
3133  // set offset depending of convex angle
3134  if (isConvexAngle()) {
3135  offset = moveMultipleElementValues.getEdgeOffset();
3136  } else {
3137  offset = shapeToMove.length2D() - moveMultipleElementValues.getEdgeOffset();
3138  }
3139  // obtain offset position
3140  const Position offsetPosition = myNBEdge->getGeometry().positionAtOffset2D(offset);
3141  // obtain nearest index to offset position
3142  const int nearestIndex = myNBEdge->getGeometry().indexOfClosest(offsetPosition);
3143  // check conditions
3144  if ((nearestIndex == -1) || (offsetPosition == Position::INVALID)) {
3145  return nullptr;
3146  } else if (offsetPosition.distanceSquaredTo2D(shapeToMove[nearestIndex]) <= (snapRadius * snapRadius)) {
3147  // move geometry point without creating new geometry point
3148  return new GNEMoveOperation(this, myNBEdge->getGeometry(), {nearestIndex}, shapeToMove, {nearestIndex});
3149  } else {
3150  // create new geometry point and keep new index (if we clicked near of shape)
3151  const int newIndex = shapeToMove.insertAtClosest(offsetPosition, true);
3152  // move after setting new geometry point in shapeToMove
3153  return new GNEMoveOperation(this, myNBEdge->getGeometry(), {nearestIndex}, shapeToMove, {newIndex});
3154  }
3155 }
3156 
3157 
3158 double
3161 }
3162 
3163 
3164 /****************************************************************************/
#define ENDPOINT_TOLERANCE
Definition: GNEEdge.cpp:59
#define VEHICLE_GAP
Definition: GNEEdge.cpp:58
@ NETWORK_DELETE
mode for deleting network elements
@ NETWORK_MOVE
mode for moving network elements
@ 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
GUIIcon
An enumeration of icons used by the gui applications.
Definition: GUIIcons.h:33
#define DEG2RAD(x)
Definition: GeomHelper.h:35
#define RAD2DEG(x)
Definition: GeomHelper.h:36
#define DEBUGCOND(PED)
#define WRITE_DEBUG(msg)
Definition: MsgHandler.h:306
#define WRITE_WARNINGF(...)
Definition: MsgHandler.h:296
#define TL(string)
Definition: MsgHandler.h:315
#define TLF(string,...)
Definition: MsgHandler.h:317
std::vector< NBEdge * > EdgeVector
container for (sorted) edges
Definition: NBCont.h:35
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_TAZSINK
a sink within a district (connection road)
@ 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_JUNCTION
begin/end of the description of a junction
@ SUMO_TAG_ROUTE
begin/end of the description of a route
@ SUMO_TAG_LANE
begin/end of the description of a single lane
@ SUMO_TAG_TYPE
type (edge)
@ SUMO_TAG_TAZSOURCE
a source within a district (connection road)
@ 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_SELECTED
element is selected
@ 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
T MIN2(T a, T b)
Definition: StdDefs.h:76
T MAX2(T a, T b)
Definition: StdDefs.h:82
const double SUMO_const_halfLaneWidth
Definition: StdDefs.h:49
std::string toString(const T &t, std::streamsize accuracy=gPrecision)
Definition: ToString.h:46
A class that stores a 2D geometrical boundary.
Definition: Boundary.h:39
void add(double x, double y, double z=0)
Makes the boundary include the given coordinate.
Definition: Boundary.cpp:78
bool isInitialised() const
check if Boundary is Initialised
Definition: Boundary.cpp:235
Boundary & grow(double by)
extends the boundary by the given amount
Definition: Boundary.cpp:319
double getHeight() const
Returns the height of the boundary (y-axis)
Definition: Boundary.cpp:160
double getWidth() const
Returns the width of the boudary (x-axis)
Definition: Boundary.cpp:154
double contains(const Boundary &b) const
return true if this boundary contains the given boundary (only X-Y)
Definition: Boundary.cpp:224
static void setColor(const RGBColor &c)
Sets the gl-color to this value.
Definition: GLHelper.cpp:654
static void popMatrix()
pop matrix
Definition: GLHelper.cpp:130
static void drawBoundary(const GUIVisualizationSettings &s, const Boundary &b)
Draw a boundary (used for debugging)
Definition: GLHelper.cpp:967
static void drawBoxLine(const Position &beg, double rot, double visLength, double width, double offset=0)
Draws a thick line.
Definition: GLHelper.cpp:295
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:539
static void pushMatrix()
push matrix
Definition: GLHelper.cpp:117
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:756
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:787
const std::string getID() const
get ID (all Attribute Carriers have one)
bool isAttributeCarrierSelected() const
check if attribute carrier is selected
bool mySelected
boolean to check if this AC is selected (instead of GUIGlObjectStorage)
static const std::string True
true value in string format (used for comparing boolean values in getAttribute(......
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)
const GNETagProperties & getTagProperty() const
get tagProperty associated with this Attribute Carrier
void unselectAttributeCarrier(const bool changeFlag=true)
unselect attribute carrier using GUIGlobalSelection
bool drawUsingSelectColor() const
check if attribute carrier must be drawn using selecting color.
GNENet * myNet
pointer to net
void selectAttributeCarrier(const bool changeFlag=true)
select attribute carrier using GUIGlobalSelection
static const std::string False
true value in string format(used for comparing boolean values in getAttribute(...))
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 markConnectionGeometryDeprecated()
check that connection's Geometry has to be updated
void updateGeometry()
update pre-computed geometry information
void updateLinkState()
recompute cached myLinkState
void calculateContourEdge(const GUIVisualizationSettings &s, const GUIVisualizationSettings::Detail d, const GNEEdge *edge, const GUIGlObject *elementToRegister, const bool closeFirstExtrem, const bool closeLastExtrem) const
calculate contour edge
Definition: GNEContour.cpp:130
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
Definition: GNEContour.cpp:307
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
Definition: GNEContour.cpp:210
void drawDottedContours(const GUIVisualizationSettings &s, const GUIVisualizationSettings::Detail d, const GNEAttributeCarrier *AC, const double lineWidth, const bool addOffset) const
drawing contour functions
Definition: GNEContour.cpp:265
void calculateContourFirstGeometryPoint(const GUIVisualizationSettings &s, const GUIVisualizationSettings::Detail d, const GUIGlObject *glObject, const PositionVector &shape, const double radius, const double scale) const
calculate contour for first geometry point
Definition: GNEContour.cpp:152
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:402
const StackPosition & getStackPosition() const
get stack position
Definition: GNEEdge.cpp:1814
const std::vector< GNEDemandElement * > & getDemandElements() const
get demand elements
Definition: GNEEdge.cpp:1820
void addDemandElements(GNEDemandElement *demandElement)
add demand elment to current StackDemandElements
Definition: GNEEdge.cpp:1808
StackDemandElements(const StackPosition stackedPosition, GNEDemandElement *demandElement)
constructor
Definition: GNEEdge.cpp:1800
Stack position (used to stack demand elements over edges)
Definition: GNEEdge.h:388
double beginPosition() const
get begin position
Definition: GNEEdge.cpp:1789
StackPosition(const double departPos, const double length)
constructor
Definition: GNEEdge.cpp:1783
double endPosition() const
get end position
Definition: GNEEdge.cpp:1795
A road/street connecting two junctions (netedit-version)
Definition: GNEEdge.h:53
const Position getFrontDownShapePosition() const
get front down shape position
Definition: GNEEdge.cpp:894
Boundary myEdgeBoundary
edge boundary
Definition: GNEEdge.h:419
void updateCenteringBoundary(const bool updateGrid)
update centering boundary (implies change in RTREE)
Definition: GNEEdge.cpp:639
void drawEdgeName(const GUIVisualizationSettings &s) const
draw edge name
Definition: GNEEdge.cpp:2758
void drawStartGeometryPoint(const GUIVisualizationSettings &s, const GUIVisualizationSettings::Detail d, const double geometryPointRadius, const double exaggeration) const
draw start extreme geometry point
Definition: GNEEdge.cpp:2630
bool isConvexAngle() const
check if edge makes a convex angle [0 - 180) degrees
Definition: GNEEdge.cpp:1733
bool checkDrawRelatedContour() const
check if draw related contour (cyan)
Definition: GNEEdge.cpp:311
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:2048
std::string getNetworkElementProblem() const
return a string with the current network element problem
Definition: GNEEdge.cpp:143
const std::map< const GNELane *, std::vector< GNEDemandElement * > > getPersonsOverEdgeMap() const
get persons a that start over this edge
Definition: GNEEdge.cpp:2515
const std::map< const GNELane *, std::vector< GNEDemandElement * > > getContainersOverEdgeMap() const
get containers a that start over this edge
Definition: GNEEdge.cpp:2548
void commitMoveShape(const GNEMoveResult &moveResult, GNEUndoList *undoList)
commit move shape
Definition: GNEEdge.cpp:2021
bool hasPredecessors() const
check if this edge has predecessors (note: only for vehicles, this function ignore walking areas!...
Definition: GNEEdge.cpp:1748
void setMoveShape(const GNEMoveResult &moveResult)
set move shape
Definition: GNEEdge.cpp:1999
void drawEndGeometryPoint(const GUIVisualizationSettings &s, const GUIVisualizationSettings::Detail d, const double geometryPointRadius, const double exaggeration) const
draw end extreme geometry point
Definition: GNEEdge.cpp:2694
bool checkDrawMoveContour() const
check if draw move contour (red)
Definition: GNEEdge.cpp:421
friend class GNEChange_Lane
Friend class.
Definition: GNEEdge.h:56
bool checkDrawOverContour() const
check if draw over contour (orange)
Definition: GNEEdge.cpp:317
~GNEEdge()
Destructor.
Definition: GNEEdge.cpp:99
void smooth(GNEUndoList *undoList)
make geometry smooth
Definition: GNEEdge.cpp:2409
void updateGeometry()
update pre-computed geometry information
Definition: GNEEdge.cpp:151
double getGeometryPointRadius() const
get geometry point radius
Definition: GNEEdge.cpp:3159
GNEMoveOperation * getMoveOperation()
get move operation
Definition: GNEEdge.cpp:463
std::string getAttributeForSelection(SumoXMLAttr key) const
method for getting the attribute in the context of object selection
Definition: GNEEdge.cpp:1213
GNEJunction * getFromJunction() const
get from Junction (only used to increase readability)
Definition: GNEEdge.h:77
void setResponsible(bool newVal)
set responsibility for deleting internal structures
Definition: GNEEdge.cpp:1504
void copyEdgeType(const GNEEdgeType *edgeType, GNEUndoList *undoList)
copy edge attributes from edgeType
Definition: GNEEdge.cpp:1050
NBEdge * getNBEdge() const
returns the internal NBEdge
Definition: GNEEdge.cpp:753
GUIGLObjectPopupMenu * getPopUpMenu(GUIMainWindow &app, GUISUMOAbstractView &parent)
Returns an own popup-menu.
Definition: GNEEdge.cpp:686
const std::map< const GNELane *, std::vector< GNEDemandElement * > > getVehiclesOverEdgeMap() const
get vehicles a that start over this edge
Definition: GNEEdge.cpp:2473
std::set< GUIGlID > getLaneGlIDs() const
returns GLIDs of all lanes
Definition: GNEEdge.cpp:1080
GNEEdge * getReverseEdge() const
get reverse edge (if exist)
Definition: GNEEdge.cpp:1770
const Position getFrontUpShapePosition() const
get front up shape position
Definition: GNEEdge.cpp:886
void setGeometry(PositionVector geom, bool inner)
update edge geometry and inform the lanes
Definition: GNEEdge.cpp:851
void smoothElevation(GNEUndoList *undoList)
smooth elevation with regard to adjoining edges
Definition: GNEEdge.cpp:2421
bool clickedOverGeometryPoint(const Position &pos) const
return true if user clicked over a Geometry Point
Definition: GNEEdge.cpp:592
bool clickedOverShapeEnd(const Position &pos) const
return true if user clicked over ShapeEnd
Definition: GNEEdge.cpp:580
void updateVehicleStackLabels()
Definition: GNEEdge.cpp:1571
GNEJunction * getToJunction() const
get from Junction (only used to increase readability)
Definition: GNEEdge.h:82
bool isValid(SumoXMLAttr key, const std::string &value)
Definition: GNEEdge.cpp:1361
void remakeGNEConnections(bool junctionsReady=false)
remake connections
Definition: GNEEdge.cpp:917
GNEMoveOperation * processMoveBothJunctionSelected()
process moving edge when both junctions are selected
Definition: GNEEdge.cpp:3111
void removeGeometryPoint(const Position clickedPosition, GNEUndoList *undoList)
remove geometry point in the clicked position
Definition: GNEEdge.cpp:495
const std::vector< GNELane * > & getLanes() const
returns a reference to the lane vector
Definition: GNEEdge.cpp:1090
LaneVector myLanes
vector with the lanes of this edge
Definition: GNEEdge.h:369
static const double SNAP_RADIUS
Definition: GNEEdge.h:308
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:1510
bool hasCustomEndPoints() const
Definition: GNEEdge.cpp:556
void updatePersonStackLabels()
Definition: GNEEdge.cpp:1629
void setEdgeID(const std::string &newID)
set edge ID
Definition: GNEEdge.cpp:2295
void removeConnection(NBEdge::Connection nbCon)
removes a connection
Definition: GNEEdge.cpp:2239
void drawChildrens(const GUIVisualizationSettings &s) const
draw children
Definition: GNEEdge.cpp:2844
bool hasSuccessors() const
check if this edge has successors (note: only for vehicles, this function ignore walking areas!...
Definition: GNEEdge.cpp:1764
bool isAttributeComputed(SumoXMLAttr key) const
Definition: GNEEdge.cpp:1481
bool drawBigGeometryPoints() const
check if draw big geometry points
Definition: GNEEdge.cpp:2989
bool myWasSplit
whether this edge was created from a split
Definition: GNEEdge.h:381
void removeLane(GNELane *lane, bool recomputeConnections)
@briefdecrease the number of lanes by one. argument is only used to increase robustness (assertions)
Definition: GNEEdge.cpp:2162
bool checkDrawSelectContour() const
check if draw select contour (blue)
Definition: GNEEdge.cpp:390
double getExaggeration(const GUIVisualizationSettings &s) const
return exaggeration associated with this GLObject
Definition: GNEEdge.cpp:627
bool hasRestrictedLane(SUMOVehicleClass vclass) const
check if edge has a restricted lane
Definition: GNEEdge.cpp:2304
static const double SNAP_RADIUS_SQUARED
Definition: GNEEdge.h:311
void updateSecondParentJunction(const std::string &value)
update last parent junction
Definition: GNEEdge.cpp:2100
std::vector< GNEEdge * > getOppositeEdges() const
get opposite edges
Definition: GNEEdge.cpp:694
PositionVector smoothShape(const PositionVector &shape, bool forElevation)
return smoothed shape
Definition: GNEEdge.cpp:2336
bool wasSplit()
whether this edge was created from a split
Definition: GNEEdge.cpp:1102
NBEdge * myNBEdge
the underlying NBEdge
Definition: GNEEdge.h:366
void copyTemplate(const GNEEdgeTemplate *edgeTemplate, GNEUndoList *undoList)
copy edge attributes from edgetemplate
Definition: GNEEdge.cpp:1027
void removeEdgeFromCrossings(GNEJunction *junction, GNEUndoList *undoList)
remove crossing of junction
Definition: GNEEdge.cpp:2315
Position getPositionInView() const
Returns position of hierarchical element in view.
Definition: GNEEdge.cpp:197
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:2109
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:2272
ConnectionVector myGNEConnections
vector with the connections of this edge
Definition: GNEEdge.h:372
void calculateEdgeContour(const GUIVisualizationSettings &s, const GUIVisualizationSettings::Detail d) const
calculate contours
Definition: GNEEdge.cpp:2870
void editEndpoint(Position pos, GNEUndoList *undoList)
makes pos the new geometry endpoint at the appropriate end, or remove current existent endpoint
Definition: GNEEdge.cpp:775
void resetBothEndpoint(GNEUndoList *undoList)
restores both endpoint to the junction position at the appropriate end
Definition: GNEEdge.cpp:841
Position getSplitPos(const Position &clickPos)
Definition: GNEEdge.cpp:759
void drawEdgeGeometryPoints(const GUIVisualizationSettings &s, const GUIVisualizationSettings::Detail d) const
draw edge geometry points (note: This function is called by GNELane::drawGL(...)
Definition: GNEEdge.cpp:2580
const std::vector< GNEConnection * > & getGNEConnections() const
returns a reference to the GNEConnection vector
Definition: GNEEdge.cpp:1096
std::string getAttribute(SumoXMLAttr key) const
Definition: GNEEdge.cpp:1108
int getRouteProbeRelativePosition(GNERouteProbe *routeProbe) const
obtain relative positions of RouteProbes
Definition: GNEEdge.cpp:992
bool checkDrawFromContour() const
check if draw from contour (green)
Definition: GNEEdge.cpp:203
std::string myConnectionStatus
modification status of the connections
Definition: GNEEdge.h:384
bool checkDrawDeleteContour() const
check if draw delete contour (pink/white)
Definition: GNEEdge.cpp:359
void deleteGLObject()
delete element
Definition: GNEEdge.cpp:738
const std::string getOptionalName() const
Returns the street name.
Definition: GNEEdge.cpp:680
void clearGNEConnections()
clear current connections
Definition: GNEEdge.cpp:965
bool myUpdateGeometry
flag to enable/disable update geometry of lanes (used mainly by setNumLanes)
Definition: GNEEdge.h:422
const Position getBackDownShapePosition() const
get back down shape position
Definition: GNEEdge.cpp:910
bool areStackPositionOverlapped(const GNEEdge::StackPosition &vehicleA, const GNEEdge::StackPosition &vehicleB) const
check if given stacked positions are overlapped
Definition: GNEEdge.cpp:3007
void updateFirstParentJunction(const std::string &value)
update front parent junction
Definition: GNEEdge.cpp:2091
void straightenElevation(GNEUndoList *undoList)
interpolate z values linear between junctions
Definition: GNEEdge.cpp:2326
void updateContainerStackLabels()
Definition: GNEEdge.cpp:1681
void drawEdgeShape(const GUIVisualizationSettings &s, const GUIVisualizationSettings::Detail d) const
draw edge shape (only one line)
Definition: GNEEdge.cpp:2954
bool checkDrawToContour() const
check if draw from contour (magenta)
Definition: GNEEdge.cpp:257
bool clickedOverShapeStart(const Position &pos) const
return true if user clicked over ShapeStart
Definition: GNEEdge.cpp:568
bool isNetworkElementValid() const
check if current network element is valid to be written into XML
Definition: GNEEdge.cpp:133
void setShapeStartPos(const Position &pos)
change Shape StartPos
Definition: GNEEdge.cpp:2451
void setAttribute(SumoXMLAttr key, const std::string &value, GNEUndoList *undoList)
Definition: GNEEdge.cpp:1223
const Position getBackUpShapePosition() const
get back up shape position
Definition: GNEEdge.cpp:902
void resetEndpoint(const Position &pos, GNEUndoList *undoList)
restores the endpoint to the junction position at the appropriate end
Definition: GNEEdge.cpp:827
bool isAttributeEnabled(SumoXMLAttr key) const
Definition: GNEEdge.cpp:1466
void drawGL(const GUIVisualizationSettings &s) const
Draws the object.
Definition: GNEEdge.cpp:700
void addConnection(NBEdge::Connection nbCon, bool selectAfterCreation=false)
adds a connection
Definition: GNEEdge.cpp:2215
void drawLaneStopOffset(const GUIVisualizationSettings &s, const GUIVisualizationSettings::Detail d) const
draw edgeStopOffset
Definition: GNEEdge.cpp:2821
GNEMoveOperation * processMoveFromJunctionSelected(const PositionVector originalShape, const Position mousePosition, const double snapRadius)
process moving edge when only from junction is selected
Definition: GNEEdge.cpp:3023
GNEMoveOperation * processNoneJunctionSelected(const double snapRadius)
process moving edge when none junction are selected
Definition: GNEEdge.cpp:3122
PositionVector getAttributePositionVector(SumoXMLAttr key) const
Definition: GNEEdge.cpp:1202
Boundary getCenteringBoundary() const
Returns the boundary to which the view shall be centered in order to show the object.
Definition: GNEEdge.cpp:633
const Parameterised::Map & getACParametersMap() const
get parameters map
Definition: GNEEdge.cpp:1498
void drawTAZElements(const GUIVisualizationSettings &s) const
draw TAZElements
Definition: GNEEdge.cpp:2893
std::vector< GNECrossing * > getGNECrossings()
get GNECrossings vinculated with this Edge
Definition: GNEEdge.cpp:1010
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:1525
void updateVehicleSpreadGeometries()
Definition: GNEEdge.cpp:1540
GNEMoveOperation * processMoveToJunctionSelected(const PositionVector originalShape, const Position mousePosition, const double snapRadius)
process moving edge when only to junction is selected
Definition: GNEEdge.cpp:3067
void updateGLObject()
update GLObject (geometry, ID, etc.)
Definition: GNEEdge.cpp:747
void updateJunctionPosition(GNEJunction *junction, const Position &origPos)
update edge geometry after junction move
Definition: GNEEdge.cpp:613
bool myAmResponsible
whether we are responsible for deleting myNBNode
Definition: GNEEdge.h:378
GNEEdge(GNENet *net, NBEdge *nbe, bool wasSplit=false, bool loaded=false)
Constructor.
Definition: GNEEdge.cpp:71
void setShapeEndPos(const Position &pos)
change Shape EndPos
Definition: GNEEdge.cpp:2462
std::string getAttribute(SumoXMLAttr key) const
const std::vector< GNELaneTemplate * > & getLaneTemplates() const
get vector with the lane templates of this edge
const std::vector< GNELaneType * > & getLaneTypes() const
get laneTypes
std::string getAttribute(SumoXMLAttr key) const
void removeCurrentEditedAttributeCarrier(const GNEAttributeCarrier *HE)
if given AttributeCarrier is the same of myHE, set it as nullptr
const std::vector< GNEJunction * > & getParentJunctions() const
get parent junctions
const std::vector< GNEDemandElement * > & getChildDemandElements() const
return child demand elements
const std::vector< GNEEdge * > & getChildEdges() const
get child edges
const std::vector< GNEAdditional * > & getChildAdditionals() const
return child additionals
void replaceParentElements(T *elementChild, const U &newParents)
replace parent elements
const std::vector< GNEGenericData * > & getChildGenericDatas() const
return child generic data 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()
update pre-computed geometry information (including crossings)
void removeOutgoingGNEEdge(GNEEdge *edge)
remove outgoing GNEEdge
void removeIncomingGNEEdge(GNEEdge *edge)
remove incoming GNEEdge
void drawGL(const GUIVisualizationSettings &s) const
Draws the object.
void addIncomingGNEEdge(GNEEdge *edge)
add incoming GNEEdge
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
This lane is powered by an underlying GNEEdge and basically knows how to draw itself.
Definition: GNELane.h:46
const PositionVector & getLaneShape() const
get elements shape
Definition: GNELane.cpp:214
int getIndex() const
returns the index of the lane
Definition: GNELane.cpp:615
double getColorValue(const GUIVisualizationSettings &s, int activeScheme) const
return value for lane coloring according to the given scheme
Definition: GNELane.cpp:1572
GNEMoveOperation * calculateMoveShapeOperation(const GUIGlObject *obj, const PositionVector originalShape, const bool maintainShapeClosed)
calculate move shape operation
bool getForceDrawGeometryPoints() const
force draw geometry points
NetworkModeOptions * getNetworkModeOptions() const
get network mode options
move operation
move result
std::vector< int > geometryPointsToMove
shape points to move (of shapeToMove)
PositionVector shapeToUpdate
shape to update (edited in moveElement)
std::vector< GNEEdge * > retrieveEdges(GNEJunction *from, GNEJunction *to) const
get all edges by from and to GNEJunction
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
const std::map< const GUIGlObject *, GNELane * > & getLanes() const
get lanes
void updateEdgeID(GNEEdge *edge, const std::string &newID)
update edge ID in container
const std::map< const GUIGlObject *, GNEConnection * > & getConnections() const
get connections
GNEEdge * retrieveEdge(const std::string &id, bool hardFail=true) const
get edge by id
void deleteLane(GNELane *lane)
delete lane from container
int getNumberOfSelectedEdges() const
get number of selected edges
void requireSaveDemandElements()
inform that demand elements has to be saved
A NBNetBuilder extended by visualisation and editing capabilities.
Definition: GNENet.h:42
void deleteEdge(GNEEdge *edge, GNEUndoList *undoList, bool recomputeConnections)
removes edge
Definition: GNENet.cpp:415
void deleteCrossing(GNECrossing *crossing, GNEUndoList *undoList)
remove crossing
Definition: GNENet.cpp:636
void addGLObjectIntoGrid(GNEAttributeCarrier *AC)
add GL Object into net
Definition: GNENet.cpp:1368
void removeGLObjectFromGrid(GNEAttributeCarrier *AC)
add GL Object into net
Definition: GNENet.cpp:1378
GNENetHelper::SavingStatus * getSavingStatus() const
get saving status
Definition: GNENet.cpp:129
void removeExplicitTurnaround(std::string id)
remove edge id from the list of explicit turnarounds
Definition: GNENet.cpp:2160
GNENetHelper::AttributeCarriers * getAttributeCarriers() const
get all attribute carriers used in this net
Definition: GNENet.cpp:123
void changeEdgeEndpoints(GNEEdge *edge, const std::string &newSourceID, const std::string &newDestID)
modifies endpoins of the given edge
Definition: GNENet.cpp:2127
GNEPathManager * getPathManager()
get path manager
Definition: GNENet.cpp:135
GNEViewNet * getViewNet() const
get view net
Definition: GNENet.cpp:2136
bool checkDrawingBoundarySelection() const
GNEContour myNetworkElementContour
network element contour
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
Representation of a RouteProbe in netedit.
Definition: GNERouteProbe.h:32
SumoXMLTag getTag() const
get Tag vinculated with this attribute Property
void end()
End undo command sub-group. If the sub-group is still empty, it will be deleted; otherwise,...
void begin(GUIIcon icon, const std::string &description)
Begin undo command sub-group with current supermode. This begins a new group of commands that are tre...
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...
GNEEdge * getEdgeFront() const
get front edge or a pointer to nullptr
const GUIGlObject * getGUIGlObjectFront() const
get front attribute carrier or a pointer to nullptr
bool isCurrentlyMovingElements() const
check if an element is being moved
const GNEViewNetHelper::DataViewOptions & getDataViewOptions() const
get data view options
Definition: GNEViewNet.cpp:747
const GNEAttributeCarrier * getFrontAttributeCarrier() const
get front attributeCarrier
const GNEViewNetHelper::EditModes & getEditModes() const
get edit modes
Definition: GNEViewNet.cpp:723
const GNEViewNetHelper::EditNetworkElementShapes & getEditNetworkElementShapes() const
get Edit Shape module
Definition: GNEViewNet.cpp:759
const GNEViewNetHelper::NetworkViewOptions & getNetworkViewOptions() const
get network view options
Definition: GNEViewNet.cpp:735
void drawTranslateFrontAttributeCarrier(const GNEAttributeCarrier *AC, double typeOrLayer, const double extraOffset=0)
draw front attributeCarrier
GNEViewParent * getViewParent() const
get the net object
bool checkOverLockedElement(const GUIGlObject *GLObject, const bool isSelected) const
check if given element is locked (used for drawing select and delete contour)
bool checkSelectEdges() const
check if select edges (toggle using button or shift)
GNEUndoList * getUndoList() const
get the undoList object
const GNEViewNetHelper::MoveMultipleElementModul & getMoveMultipleElementValues() const
get move multiple element values
Definition: GNEViewNet.cpp:547
const GNEViewNetHelper::ViewObjectsSelector & getViewObjectsSelector() const
get objects under cursor
Definition: GNEViewNet.cpp:477
void removeFromAttributeCarrierInspected(const GNEAttributeCarrier *AC)
remove given AC of list of inspected Attribute Carriers
const std::vector< GNEAttributeCarrier * > & getInspectedAttributeCarriers() const
get inspected attribute carriers
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.
static void drawGeometry(const GUIVisualizationSettings::Detail d, const GUIGeometry &geometry, const double width, double offset=0)
draw geometry
GUIGlObjectType getType() const
Returns the type of the object as coded in GUIGlObjectType.
Definition: GUIGlObject.h:156
const std::string & getMicrosimID() const
Returns the id of the object as known to microsim.
Definition: GUIGlObject.h:143
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)
virtual Position getPositionInformation() const
Returns the cursor's x/y position within the network.
bool isElementSelected(const GUIGlObject *GLObject) const
check if element was already selected
const Boundary & getSelectionBoundary() const
get selection boundary (usually the mouse position)
const std::vector< int > & getGeometryPoints(const GUIGlObject *GLObject) const
get geometry points for the given glObject
bool addElementUnderCursor(const GUIGlObject *GLObject, const bool checkDuplicated, const bool fullBoundary)
add element into list of elements under cursor
const GUIGlObject * markedFirstGeometryPoint
marked first geometry point (used for moving/delete geometry points)
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
bool spreadSuperposed
Whether to improve visualisation of superposed (rail) edges.
GUIColorer junctionColorer
The junction colorer.
std::string edgeParam
key for coloring by edge parameter
bool checkBoundarySizeDrawing(const double w, const double h) const
check if draw element depending of boundarySize
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:670
void mirrorX()
mirror coordinates along the x-axis
Definition: NBEdge.cpp:564
void setPreferredVehicleClass(SVCPermissions permissions, int lane=-1)
set preferred Vehicle Class
Definition: NBEdge.cpp:4345
SVCPermissions getPermissions(int lane=-1) const
get the union of allowed classes over all lanes or for a specific lane
Definition: NBEdge.cpp:4368
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:4331
StopOffset myEdgeStopOffset
A vClass specific stop offset - assumed of length 0 (unspecified) or 1. For the latter case the int i...
Definition: NBEdge.h:1796
double getLoadedLength() const
Returns the length was set explicitly or the computed length if it wasn't set.
Definition: NBEdge.h:598
void setSpeed(int lane, double speed)
set lane specific speed (negative lane implies set for all lanes)
Definition: NBEdge.cpp:4283
bool hasLaneSpecificFriction() const
whether lanes differ in friction
Definition: NBEdge.cpp:2450
double getLaneWidth() const
Returns the default width of lanes of this edge.
Definition: NBEdge.h:638
const std::string & getStreetName() const
Returns the street name of this edge.
Definition: NBEdge.h:665
void addLane(int index, bool recomputeShape, bool recomputeConnections, bool shiftIndices)
add lane
Definition: NBEdge.cpp:4020
bool hasLaneSpecificSpeed() const
whether lanes differ in speed
Definition: NBEdge.cpp:2440
std::string myType
The type of the edge.
Definition: NBEdge.h:1733
LaneSpreadFunction getLaneSpreadFunction() const
Returns how this edge's lanes' lateral offset is computed.
Definition: NBEdge.cpp:992
bool hasLoadedLength() const
Returns whether a length was set explicitly.
Definition: NBEdge.h:608
void setDistance(double distance)
set kilometrage at start of edge (negative value implies couting down along the edge)
Definition: NBEdge.h:1409
const std::string & getID() const
Definition: NBEdge.h:1524
const std::vector< NBEdge::Lane > & getLanes() const
Returns the lane definitions.
Definition: NBEdge.h:726
NBNode * getToNode() const
Returns the destination node of the edge.
Definition: NBEdge.h:542
double getSpeed() const
Returns the speed allowed on this edge.
Definition: NBEdge.h:615
double getDistance() const
get distance
Definition: NBEdge.h:675
static const double UNSPECIFIED_LOADED_LENGTH
no length override given
Definition: NBEdge.h:360
void setLaneWidth(int lane, double width)
set lane specific width (negative lane implies set for all lanes)
Definition: NBEdge.cpp:4154
void setLaneSpreadFunction(LaneSpreadFunction spread)
(Re)sets how the lanes lateral offset shall be computed
Definition: NBEdge.cpp:986
bool isTurningDirectionAt(const NBEdge *const edge) const
Returns whether the given edge is the opposite direction to this edge.
Definition: NBEdge.cpp:3654
bool hasLaneSpecificPermissions() const
whether lanes differ in allowed vehicle classes
Definition: NBEdge.cpp:2426
bool isBidiEdge(bool checkPotential=false) const
whether this edge is part of a bidirectional edge pair
Definition: NBEdge.cpp:755
void setBidi(bool isBidi)
mark this edge as a bidi edge
Definition: NBEdge.h:1414
int getNumLanes() const
Returns the number of lanes.
Definition: NBEdge.h:516
const PositionVector & getGeometry() const
Returns the geometry of the edge.
Definition: NBEdge.h:779
void setFriction(int lane, double friction)
set lane specific friction (negative lane implies set for all lanes)
Definition: NBEdge.cpp:4299
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:1441
void invalidateConnections(bool reallowSetting=false)
invalidate current connections of edge
Definition: NBEdge.cpp:1522
void deleteLane(int index, bool recompute, bool shiftIndices)
delete lane
Definition: NBEdge.cpp:4075
bool hasLaneSpecificWidth() const
whether lanes differ in width
Definition: NBEdge.cpp:2460
@ USER
The connection was given by the user.
double getFriction() const
Returns the friction on this edge.
Definition: NBEdge.h:622
const NBEdge * getBidiEdge() const
Definition: NBEdge.h:1510
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:1179
bool hasLaneSpecificEndOffset() const
whether lanes differ in offset
Definition: NBEdge.cpp:2482
NBEdge * getTurnDestination(bool possibleDestination=false) const
Definition: NBEdge.cpp:3997
int getPriority() const
Returns the priority of the edge.
Definition: NBEdge.h:523
static const double UNSPECIFIED_WIDTH
unspecified lane width
Definition: NBEdge.h:342
const std::vector< Connection > & getConnections() const
Returns the connections.
Definition: NBEdge.h:1037
const std::string & getTypeID() const
get ID of type
Definition: NBEdge.h:1177
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:1438
double getEndOffset() const
Returns the offset to the destination node.
Definition: NBEdge.h:685
void setEndOffset(int lane, double offset)
set lane specific end-offset (negative lane implies set for all lanes)
Definition: NBEdge.cpp:4237
Lane & getLaneStruct(int lane)
Definition: NBEdge.h:1424
void setLoadedLength(double val)
set loaded length
Definition: NBEdge.cpp:4383
const PositionVector getInnerGeometry() const
Returns the geometry of the edge without the endpoints.
Definition: NBEdge.cpp:584
double getFinalLength() const
get length that will be assigned to the lanes in the final network
Definition: NBEdge.cpp:4704
void setGeometry(const PositionVector &g, bool inner=false)
(Re)sets the edge's geometry
Definition: NBEdge.cpp:631
int myPriority
The priority of the edge.
Definition: NBEdge.h:1752
NBNode * getFromNode() const
Returns the origin node of the edge.
Definition: NBEdge.h:535
const EdgeVector & getOutgoingEdges() const
Returns this node's outgoing edges (The edges which start at this node)
Definition: NBNode.h:273
const EdgeVector & getIncomingEdges() const
Returns this node's incoming edges (The edges which yield in this node)
Definition: NBNode.h:268
const Position & getPosition() const
Definition: NBNode.h:260
bool isRoundabout() const
return whether this node is part of a roundabout
Definition: NBNode.cpp:3827
bool geometryLike() const
whether this is structurally similar to a geometry node
Definition: NBNode.cpp:3781
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:575
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.
Definition: OptionsCont.cpp:60
static bool areParametersValid(const std::string &value, bool report=false, const std::string kvsep="=", const std::string sep="|")
check if given string can be parsed to a parameters map "key1=value1|key2=value2|....
std::map< std::string, std::string > Map
parameters map
Definition: Parameterised.h:45
void setParametersStr(const std::string &paramsString, const std::string kvsep="=", const std::string sep="|")
set the inner key/value map in string format "key1=value1|key2=value2|...|keyN=valueN"
virtual const std::string getParameter(const std::string &key, const std::string defaultValue="") const
Returns the value for a given key.
const Parameterised::Map & getParametersMap() const
Returns the inner key/value map.
std::string getParametersStr(const std::string kvsep="=", const std::string sep="|") const
Returns the inner key/value map in string format "key1=value1|key2=value2|...|keyN=valueN".
A point in 2D or 3D with translation and scaling methods.
Definition: Position.h:37
double distanceSquaredTo2D(const Position &p2) const
returns the square of the distance to another position (Only using x and y positions)
Definition: Position.h:281
static const Position INVALID
used to indicate that a position is valid
Definition: Position.h:322
double distanceTo2D(const Position &p2) const
returns the euclidean distance in the x-y-plane
Definition: Position.h:276
void add(const Position &pos)
Adds the given position to this one.
Definition: Position.h:132
void mul(double val)
Multiplies position with the given value.
Definition: Position.h:105
double z() const
Returns the z-position.
Definition: Position.h:65
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
int insertAtClosest(const Position &p, bool interpolateZ)
inserts p between the two closest positions
void push_front(const Position &p)
insert in front a Position
void removeDoublePoints(double minDist=POSITION_EPS, bool assertLength=false, int beginOffset=0, int endOffset=0, bool resample=false)
Removes positions if too near.
void pop_front()
pop first Position
PositionVector reverse() const
reverse position vector
Position positionAtOffset2D(double pos, double lateralOffset=0) const
Returns the position at the given length.
static const RGBColor BLUE
Definition: RGBColor.h:187
unsigned char alpha() const
Returns the alpha-amount of the color.
Definition: RGBColor.cpp:92
static const RGBColor ORANGE
Definition: RGBColor.h:191
static const RGBColor CYAN
Definition: RGBColor.h:189
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
bool hasString(const std::string &str) const
const std::string & getString(const T key) const
auto get(const nlohmann::detail::iteration_proxy_value< IteratorType > &i) -> decltype(i.key())
Definition: json.hpp:4451
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
bool isMovingSelectedEdge() const
flag for moving edge
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:297
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
double friction
Definition: NBEdge.h:243
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