Eclipse SUMO - Simulation of Urban MObility
GNEGeometry.cpp
Go to the documentation of this file.
1 /****************************************************************************/
2 // Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.org/sumo
3 // Copyright (C) 2001-2019 German Aerospace Center (DLR) and others.
4 // This program and the accompanying materials
5 // are made available under the terms of the Eclipse Public License v2.0
6 // which accompanies this distribution, and is available at
7 // http://www.eclipse.org/legal/epl-v20.html
8 // SPDX-License-Identifier: EPL-2.0
9 /****************************************************************************/
14 // File for geometry classes and functions
15 /****************************************************************************/
16 
17 
18 // ===========================================================================
19 // included modules
20 // ===========================================================================
21 
26 #include <utils/gui/div/GLHelper.h>
28 
29 #include "GNEGeometry.h"
30 #include "GNEViewNet.h"
31 
32 
33 // ===========================================================================
34 // method definitions
35 // ===========================================================================
36 
37 // ---------------------------------------------------------------------------
38 // GNEGeometry::Geometry - methods
39 // ---------------------------------------------------------------------------
40 
42  myPosition(Position::INVALID),
43  myRotation(0) {
44 }
45 
46 
47 void
48 GNEGeometry::Geometry::updateGeometryShape(const PositionVector& shape, double startPos, double endPos,
49  const Position& extraFirstPosition, const Position& extraLastPosition) {
50  // set new shape
51  myShape = shape;
52  // check if we have to split the lane
53  if ((startPos != -1) || (endPos != -1)) {
54  // check if both start and end position must be swapped
55  if ((startPos != -1) && (endPos != -1) && (endPos < startPos)) {
56  std::swap(startPos, endPos);
57  }
58  // check that split positions are correct
59  if (startPos <= POSITION_EPS) {
60  if (endPos == -1) {
61  // leave shape unmodified
62  } else if (endPos <= POSITION_EPS) {
63  // use only first shape position
64  myShape = PositionVector({myShape.front()});
65  } else if (endPos < (shape.length() - POSITION_EPS)) {
66  // split shape using end position and use left part
67  myShape = myShape.splitAt(endPos).first;
68  }
69  } else if (startPos >= (shape.length() - POSITION_EPS)) {
70  // use only last position
71  myShape = PositionVector({myShape.back()});
72  } else if (endPos == -1) {
73  // split shape using start position and use the right part
74  myShape = myShape.splitAt(startPos).second;
75  } else if (endPos <= POSITION_EPS) {
76  // use only first shape position
77  myShape = PositionVector({myShape.front()});
78  } else if (endPos >= (shape.length() - POSITION_EPS)) {
79  // split shape using start position and use the right part
80  myShape = myShape.splitAt(startPos).second;
81  } else {
82  // split shape using start and end position
83  myShape = myShape.getSubpart(startPos, endPos);
84  }
85  }
86  // check if we have to add an extra first position
87  if (extraFirstPosition != Position::INVALID) {
88  myShape.push_front(extraFirstPosition);
89  }
90  // check if we have to add an extra last position
91  if (extraLastPosition != Position::INVALID) {
92  myShape.push_back(extraLastPosition);
93  }
94  // calculate shape rotation and lengths
95  calculateShapeRotationsAndLengths();
96 }
97 
98 
99 void
100 GNEGeometry::Geometry::updateGeometryPosition(const GNELane* lane, const double posOverLane) {
101  // get lane length
102  const double laneLength = lane->getLaneShape().length();
103  // calculate position and rotation
104  if (posOverLane < 0) {
105  myPosition = lane->getLaneShape().positionAtOffset(0);
106  myRotation = (lane->getLaneShape().rotationDegreeAtOffset(0) * -1);
107  } else if (posOverLane > laneLength) {
108  myPosition = lane->getLaneShape().positionAtOffset(laneLength);
109  myRotation = (lane->getLaneShape().rotationDegreeAtOffset(laneLength) * -1);
110  } else {
111  myPosition = lane->getLaneShape().positionAtOffset(posOverLane);
112  myRotation = (lane->getLaneShape().rotationDegreeAtOffset(posOverLane) * -1);
113  }
114 }
115 
116 
117 void
119  // copy geometry of additional
120  myShape = additional->getAdditionalGeometry().getShape();
121  myShapeLengths = additional->getAdditionalGeometry().getShapeLengths();
122  myShapeRotations = additional->getAdditionalGeometry().getShapeRotations();
123 }
124 
125 
126 const Position&
128  if (myPosition == Position::INVALID) {
129  throw ProcessError("invalid single position");
130  } else {
131  return myPosition;
132  }
133 }
134 
135 
136 double
138  if (myPosition == Position::INVALID) {
139  throw ProcessError("invalid single rotation");
140  } else {
141  return myRotation;
142  }
143 }
144 
145 
146 const PositionVector&
148  return myShape;
149 }
150 
151 
152 const std::vector<double>&
154  return myShapeRotations;
155 }
156 
157 
158 const std::vector<double>&
160  return myShapeLengths;
161 }
162 
163 
164 void
166  // clear rotations and lengths
167  myShapeRotations.clear();
168  myShapeLengths.clear();
169  // Get number of parts of the shape
170  int numberOfSegments = (int)myShape.size() - 1;
171  // If number of segments is more than 0
172  if (numberOfSegments >= 0) {
173  // Reserve memory (To improve efficiency)
174  myShapeRotations.reserve(numberOfSegments);
175  myShapeLengths.reserve(numberOfSegments);
176  // Calculate lengths and rotations for every shape
177  for (int i = 0; i < numberOfSegments; i++) {
178  myShapeRotations.push_back(calculateRotation(myShape[i], myShape[i + 1]));
179  myShapeLengths.push_back(calculateLength(myShape[i], myShape[i + 1]));
180  }
181  }
182 }
183 
184 // ---------------------------------------------------------------------------
185 // GNEGeometry::SegmentGeometry::Segment - methods
186 // ---------------------------------------------------------------------------
187 
188 GNEGeometry::SegmentGeometry::Segment::Segment(const GNEAttributeCarrier* _AC, const GNELane* _lane, const bool _valid) :
189  AC(_AC),
190  edge(_lane->getParentEdge()),
191  lane(_lane),
192  junction(nullptr),
193  valid(_valid),
194  myUseLaneShape(true),
195  myUseLane2LaneShape(false) {
196 }
197 
198 
200  const PositionVector& shape, const std::vector<double>& shapeRotations, const std::vector<double>& shapeLengths, const bool _valid) :
201  AC(_AC),
202  edge(_lane->getParentEdge()),
203  lane(_lane),
204  junction(nullptr),
205  valid(_valid),
206  myUseLaneShape(false),
207  myUseLane2LaneShape(false),
208  mySegmentShape(shape),
209  mySegmentRotations(shapeRotations),
210  mySegmentLengths(shapeLengths) {
211 }
212 
213 
214 GNEGeometry::SegmentGeometry::Segment::Segment(const GNEAttributeCarrier* _AC, const GNELane* currentLane, const GNELane* nextLane, const bool _valid) :
215  AC(_AC),
216  edge(nullptr),
217  lane(nextLane),
218  junction(currentLane->getParentEdge()->getGNEJunctionDestiny()),
219  valid(_valid),
220  myUseLaneShape(false),
221  myUseLane2LaneShape(true),
222  mySegmentShape(currentLane->getLane2laneConnections().connectionsMap.at(nextLane).getShape()),
223  mySegmentRotations(currentLane->getLane2laneConnections().connectionsMap.at(nextLane).getShapeRotations()),
224  mySegmentLengths(currentLane->getLane2laneConnections().connectionsMap.at(nextLane).getShapeLengths()) {
225 }
226 
227 
228 void
229 GNEGeometry::SegmentGeometry::Segment::update(const PositionVector& shape, const std::vector<double>& shapeRotations, const std::vector<double>& shapeLengths) {
230  mySegmentShape = shape;
231  mySegmentRotations = shapeRotations;
232  mySegmentLengths = shapeLengths;
233 }
234 
235 
236 GNEGeometry::SegmentGeometry::SegmentToUpdate::SegmentToUpdate(const int _index, const GNELane* _lane, const GNELane* _nextLane) :
237  index(_index),
238  lane(_lane),
239  nextLane(_nextLane) {
240 }
241 
242 
243 const PositionVector&
245  if (myUseLaneShape) {
246  return lane->getLaneShape();
247  } else {
248  return mySegmentShape;
249  }
250 }
251 
252 
253 const std::vector<double>&
255  if (myUseLaneShape) {
256  return lane->getShapeRotations();
257  } else {
258  return mySegmentRotations;
259  }
260 }
261 
262 
263 const std::vector<double>&
265  if (myUseLaneShape) {
266  return lane->getShapeLengths();
267  } else {
268  return mySegmentLengths;
269  }
270 }
271 
272 // ---------------------------------------------------------------------------
273 // GNEGeometry::Geometry - methods
274 // ---------------------------------------------------------------------------
275 
277 
278 
279 void
281  // add segment in myShapeSegments
282  myShapeSegments.push_back(Segment(AC, lane, valid));
283 }
284 
285 
286 void
288  const PositionVector& laneShape, const std::vector<double>& laneShapeRotations, const std::vector<double>& laneShapeLengths, const bool valid) {
289  // add segment in myShapeSegments
290  myShapeSegments.push_back(Segment(AC, lane, laneShape, laneShapeRotations, laneShapeLengths, valid));
291 }
292 
293 
294 void
295 GNEGeometry::SegmentGeometry::insertLane2LaneSegment(const GNEAttributeCarrier* AC, const GNELane* currentLane, const GNELane* nextLane, const bool valid) {
296  // add segment in myShapeSegments
297  myShapeSegments.push_back(Segment(AC, currentLane, nextLane, valid));
298 }
299 
300 
301 void
302 GNEGeometry::SegmentGeometry::updateCustomSegment(const int segmentIndex, const PositionVector& newLaneShape, const std::vector<double>& newLaneShapeRotations, const std::vector<double>& newLaneShapeLengths) {
303  myShapeSegments.at(segmentIndex).update(newLaneShape, newLaneShapeRotations, newLaneShapeLengths);
304 }
305 
306 
307 void
308 GNEGeometry::SegmentGeometry::updateLane2LaneSegment(const int segmentIndex, const GNELane* lane, const GNELane* nextLane) {
309  myShapeSegments.at(segmentIndex + 1).update(
310  lane->getLane2laneConnections().connectionsMap.at(nextLane).getShape(),
311  lane->getLane2laneConnections().connectionsMap.at(nextLane).getShapeRotations(),
312  lane->getLane2laneConnections().connectionsMap.at(nextLane).getShapeLengths());
313 }
314 
315 
316 void
318  // clear segments
319  myShapeSegments.clear();
320 }
321 
322 
323 const Position&
325  if ((myShapeSegments.size() > 0) && (myShapeSegments.front().getShape().size() > 0)) {
326  return myShapeSegments.front().getShape().front();
327  } else {
328  return Position::INVALID;
329  }
330 }
331 
332 const Position&
334  if ((myShapeSegments.size() > 0) && (myShapeSegments.back().getShape().size() > 0)) {
335  return myShapeSegments.back().getShape().back();
336  } else {
337  return Position::INVALID;
338  }
339 }
340 
341 
342 double
344  if ((myShapeSegments.size() > 0) && (myShapeSegments.front().getShapeRotations().size() > 0)) {
345  return myShapeSegments.front().getShapeRotations().front();
346  } else {
347  return 0;
348  }
349 }
350 
351 
352 Boundary
354  Boundary b;
355  for (const auto& i : myShapeSegments) {
356  b.add(i.getShape().getBoxBoundary());
357  }
358  return b;
359 }
360 
361 
362 std::vector<GNEGeometry::SegmentGeometry::Segment>::const_iterator
364  return myShapeSegments.cbegin();
365 }
366 
367 
368 std::vector<GNEGeometry::SegmentGeometry::Segment>::const_iterator
370  return myShapeSegments.cend();
371 }
372 
373 
376  return myShapeSegments.front();
377 }
378 
379 
382  return myShapeSegments.back();
383 }
384 
385 
386 int
388  return (int)myShapeSegments.size();
389 }
390 
391 // ---------------------------------------------------------------------------
392 // GNEGeometry::Lane2laneConnection - methods
393 // ---------------------------------------------------------------------------
394 
396  myOriginLane(originLane) {
397 }
398 
399 
400 void
402  // clear connectionsMap
403  connectionsMap.clear();
404  // iterate over outgoingEdge's lanes
405  for (const auto& outgoingEdge : myOriginLane->getParentEdge()->getGNEJunctionDestiny()->getGNEOutgoingEdges()) {
406  for (const auto& outgoingLane : outgoingEdge->getLanes()) {
407  // get NBEdges from and to
408  const NBEdge* NBEdgeFrom = myOriginLane->getParentEdge()->getNBEdge();
409  const NBEdge* NBEdgeTo = outgoingLane->getParentEdge()->getNBEdge();
410  // only create smooth shapes if Edge From has as maximum 10 lanes
411  if ((NBEdgeFrom->getNumLanes() <= 10) && (NBEdgeFrom->getToNode()->getShape().area() > 4)) {
412  // Calculate smooth shape
413  connectionsMap[outgoingLane].updateGeometryShape(NBEdgeFrom->getToNode()->computeSmoothShape(
414  NBEdgeFrom->getLaneShape(myOriginLane->getIndex()),
415  NBEdgeTo->getLaneShape(outgoingLane->getIndex()),
416  5, NBEdgeFrom->getTurnDestination() == NBEdgeTo,
417  (double) 5. * (double) NBEdgeFrom->getNumLanes(),
418  (double) 5. * (double) NBEdgeTo->getNumLanes()));
419  } else {
420  // create a shape using shape extremes
421  connectionsMap[outgoingLane].updateGeometryShape({
422  NBEdgeFrom->getLaneShape(myOriginLane->getIndex()).back(),
423  NBEdgeTo->getLaneShape(outgoingLane->getIndex()).front()});
424  }
425 
426  }
427  }
428 }
429 
430 // ---------------------------------------------------------------------------
431 // GNEHierarchicalParentElements::ParentConnections - methods
432 // ---------------------------------------------------------------------------
433 
435  myHierarchicalElement(hierarchicalElement) {}
436 
437 
438 void
440  // first clear connection positions
441  connectionPositions.clear();
442  symbolsPositionAndRotation.clear();
443  // calculate position and rotation of every simbol for every edge
444  for (const auto& edge : myHierarchicalElement->getParentEdges()) {
445  for (const auto& lane : edge->getLanes()) {
446  std::pair<Position, double> posRot;
447  // set position and length depending of shape's lengt
448  if (lane->getLaneShape().length() - 6 > 0) {
449  posRot.first = lane->getLaneShape().positionAtOffset(lane->getLaneShape().length() - 6);
450  posRot.second = lane->getLaneShape().rotationDegreeAtOffset(lane->getLaneShape().length() - 6);
451  } else {
452  posRot.first = lane->getLaneShape().positionAtOffset(lane->getLaneShape().length());
453  posRot.second = lane->getLaneShape().rotationDegreeAtOffset(lane->getLaneShape().length());
454  }
455  symbolsPositionAndRotation.push_back(posRot);
456  }
457  }
458  // calculate position and rotation of every symbol for every lane
459  for (const auto& lane : myHierarchicalElement->getParentLanes()) {
460  std::pair<Position, double> posRot;
461  // set position and length depending of shape's lengt
462  if (lane->getLaneShape().length() - 6 > 0) {
463  posRot.first = lane->getLaneShape().positionAtOffset(lane->getLaneShape().length() - 6);
464  posRot.second = lane->getLaneShape().rotationDegreeAtOffset(lane->getLaneShape().length() - 6);
465  } else {
466  posRot.first = lane->getLaneShape().positionAtOffset(lane->getLaneShape().length());
467  posRot.second = lane->getLaneShape().rotationDegreeAtOffset(lane->getLaneShape().length());
468  }
469  symbolsPositionAndRotation.push_back(posRot);
470  }
471  // calculate position for every parent additional
472  for (const auto& additional : myHierarchicalElement->getParentAdditionals()) {
473  // check that position is different of position
474  if (additional->getPositionInView() != myHierarchicalElement->getPositionInView()) {
475  std::vector<Position> posConnection;
476  double A = std::abs(additional->getPositionInView().x() - myHierarchicalElement->getPositionInView().x());
477  double B = std::abs(additional->getPositionInView().y() - myHierarchicalElement->getPositionInView().y());
478  // Set positions of connection's vertex. Connection is build from Entry to E3
479  posConnection.push_back(additional->getPositionInView());
480  if (myHierarchicalElement->getPositionInView().x() > additional->getPositionInView().x()) {
481  if (myHierarchicalElement->getPositionInView().y() > additional->getPositionInView().y()) {
482  posConnection.push_back(Position(additional->getPositionInView().x() + A, additional->getPositionInView().y()));
483  } else {
484  posConnection.push_back(Position(additional->getPositionInView().x(), additional->getPositionInView().y() - B));
485  }
486  } else {
487  if (myHierarchicalElement->getPositionInView().y() > additional->getPositionInView().y()) {
488  posConnection.push_back(Position(additional->getPositionInView().x(), additional->getPositionInView().y() + B));
489  } else {
490  posConnection.push_back(Position(additional->getPositionInView().x() - A, additional->getPositionInView().y()));
491  }
492  }
493  posConnection.push_back(myHierarchicalElement->getPositionInView());
494  connectionPositions.push_back(posConnection);
495  }
496  }
497  // calculate geometry for connections between parent and parents
498  for (const auto& symbol : symbolsPositionAndRotation) {
499  std::vector<Position> posConnection;
500  double A = std::abs(symbol.first.x() - myHierarchicalElement->getPositionInView().x());
501  double B = std::abs(symbol.first.y() - myHierarchicalElement->getPositionInView().y());
502  // Set positions of connection's vertex. Connection is build from Entry to E3
503  posConnection.push_back(symbol.first);
504  if (myHierarchicalElement->getPositionInView().x() > symbol.first.x()) {
505  if (myHierarchicalElement->getPositionInView().y() > symbol.first.y()) {
506  posConnection.push_back(Position(symbol.first.x() + A, symbol.first.y()));
507  } else {
508  posConnection.push_back(Position(symbol.first.x(), symbol.first.y() - B));
509  }
510  } else {
511  if (myHierarchicalElement->getPositionInView().y() > symbol.first.y()) {
512  posConnection.push_back(Position(symbol.first.x(), symbol.first.y() + B));
513  } else {
514  posConnection.push_back(Position(symbol.first.x() - A, symbol.first.y()));
515  }
516  }
517  posConnection.push_back(myHierarchicalElement->getPositionInView());
518  connectionPositions.push_back(posConnection);
519  }
520 }
521 
522 
523 void
525  // Iterate over myConnectionPositions
526  for (const PositionVector& connectionPosition : connectionPositions) {
527  // Add a draw matrix
528  glPushMatrix();
529  // translate in the Z axis
530  glTranslated(0, 0, parentType - 0.01);
531  // Set color of the base
533  // iterate over connections
534  for (PositionVector::const_iterator j = connectionPosition.begin(); (j + 1) != connectionPosition.end(); ++j) {
535  // Draw Lines
536  GLHelper::drawLine((*j), (*(j + 1)));
537  }
538  // Pop draw matrix
539  glPopMatrix();
540  }
541 }
542 
543 // ---------------------------------------------------------------------------
544 // GNEGeometry - methods
545 // ---------------------------------------------------------------------------
546 
547 double
548 GNEGeometry::calculateRotation(const Position& first, const Position& second) {
549  // return rotation (angle) of the vector constructed by points first and second
550  return ((double)atan2((second.x() - first.x()), (first.y() - second.y())) * (double) 180.0 / (double)M_PI);
551 }
552 
553 
554 double
555 GNEGeometry::calculateLength(const Position& first, const Position& second) {
556  // return 2D distance between two points
557  return first.distanceTo2D(second);
558 }
559 
560 
561 void
562 GNEGeometry::adjustStartPosGeometricPath(double& startPos, const GNELane* startLane, double& endPos, const GNELane* endLane) {
563  // adjust both, if start and end lane are the same
564  if (startLane && endLane && (startLane == endLane) && (startPos != -1) && (endPos != -1)) {
565  if (startPos >= endPos) {
566  endPos = (startPos + POSITION_EPS);
567  }
568  }
569  // adjust startPos
570  if ((startPos != -1) && startLane) {
571  if (startPos < POSITION_EPS) {
572  startPos = POSITION_EPS;
573  }
574  if (startPos > (startLane->getLaneShape().length() - POSITION_EPS)) {
575  startPos = (startLane->getLaneShape().length() - POSITION_EPS);
576  }
577  }
578  // adjust endPos
579  if ((endPos != -1) && endLane) {
580  if (endPos < POSITION_EPS) {
581  endPos = POSITION_EPS;
582  }
583  if (endPos > (endLane->getLaneShape().length() - POSITION_EPS)) {
584  endPos = (endLane->getLaneShape().length() - POSITION_EPS);
585  }
586  }
587 }
588 
589 
590 void
592  const std::vector<GNEEdge*>& edges, const SUMOVehicleClass vClass, GNELane* fromLane, GNELane* toLane, double startPos, double endPos,
593  const Position& extraFirstPosition, const Position& extraLastPosition) {
594  // clear geometry
595  segmentGeometry.clearSegmentGeometry();
596  // first check that there is parent edges
597  if (edges.size() > 0) {
598  // calculate depending if both from and to edges are the same
599  if (fromLane == toLane) {
600  // if obtained lane is null, then force to use first lane
601  if (fromLane == nullptr) {
602  calculateLaneGeometricPath(AC, segmentGeometry, {edges.front()->getLanes().front()}, startPos, endPos, extraFirstPosition, extraLastPosition);
603  } else {
604  calculateLaneGeometricPath(AC, segmentGeometry, {fromLane}, startPos, endPos, extraFirstPosition, extraLastPosition);
605  }
606  } else {
607  // declare vector of lanes
608  std::vector<GNELane*> lanes;
609  // reserve space
610  lanes.reserve(edges.size());
611  // obtain lanes by VClass
612  for (auto edgeParent = edges.begin(); edgeParent != edges.end(); edgeParent++) {
613  GNELane* allowedLane = nullptr;
614  if (edgeParent == edges.begin()) {
615  allowedLane = fromLane;
616  } else if (edgeParent == (edges.end() - 1)) {
617  allowedLane = toLane;
618  } else if (AC->getTagProperty().isRide()) {
619  // obtain first disallowed lane (special case for rides)
620  allowedLane = (*edgeParent)->getLaneByDisallowedVClass(vClass);
621  } else {
622  // obtain first allowed lane
623  allowedLane = (*edgeParent)->getLaneByAllowedVClass(vClass);
624  }
625  // if there isn't allowed lane, then use first lane
626  if (allowedLane == nullptr) {
627  allowedLane = (*edgeParent)->getLanes().front();
628  }
629  // add it to lanes
630  lanes.push_back(allowedLane);
631  }
632  // calculate geometric path
633  calculateLaneGeometricPath(AC, segmentGeometry, lanes, startPos, endPos, extraFirstPosition, extraLastPosition);
634  }
635  }
636 }
637 
638 
639 void
640 GNEGeometry::calculateLaneGeometricPath(const GNEAttributeCarrier* AC, GNEGeometry::SegmentGeometry& segmentGeometry, const std::vector<GNELane*>& lanes,
641  double startPos, double endPos, const Position& extraFirstPosition, const Position& extraLastPosition) {
642  // clear geometry
643  segmentGeometry.clearSegmentGeometry();
644  // first check that there is parent edges
645  if (lanes.size() > 0) {
646  // calculate depending if both from and to edges are the same
647  if (lanes.size() == 1) {
648  // filter start and end pos
649  adjustStartPosGeometricPath(startPos, lanes.front(), endPos, lanes.front());
650  // check if we have to define a new custom Segment, or we can use the commonLane shape
651  if ((startPos != -1) || (endPos != -1) || (extraFirstPosition != Position::INVALID) || (extraLastPosition != Position::INVALID)) {
652  // declare a lane to be trimmed
653  Geometry trimmedLane;
654  // update geometry
655  trimmedLane.updateGeometryShape(lanes.front()->getLaneShape(), startPos, endPos, extraFirstPosition, extraLastPosition);
656  // add sublane geometry
657  segmentGeometry.insertCustomSegment(AC, lanes.front(),
658  trimmedLane.getShape(),
659  trimmedLane.getShapeRotations(),
660  trimmedLane.getShapeLengths(), true);
661  } else {
662  // add entire lane geometry geometry
663  segmentGeometry.insertLaneSegment(AC, lanes.front(), true);
664  }
665  } else {
666  // iterate over lanes
667  for (int i = 0; i < (int)lanes.size(); i++) {
668  // get lane (only for code readability)
669  const GNELane* lane = lanes.at(i);
670  // first check that lane shape isn't empty
671  if (lane->getLaneShape().size() > 0) {
672  // check if first or last lane must be splitted
673  if ((lanes.at(i) == lanes.front()) && (startPos != -1)) {
674  // filter start position
675  adjustStartPosGeometricPath(startPos, lanes.at(i), endPos, nullptr);
676  // declare a lane to be trimmed
677  Geometry frontTrimmedLane;
678  // update geometry
679  frontTrimmedLane.updateGeometryShape(lanes.at(i)->getLaneShape(), startPos, -1, extraFirstPosition, Position::INVALID);
680  // add sublane geometry
681  segmentGeometry.insertCustomSegment(AC, lane,
682  frontTrimmedLane.getShape(),
683  frontTrimmedLane.getShapeRotations(),
684  frontTrimmedLane.getShapeLengths(), true);
685  } else if ((lane == lanes.back()) && (endPos != -1)) {
686  // filter end position
687  adjustStartPosGeometricPath(startPos, nullptr, endPos, lane);
688  // declare a lane to be trimmed
689  Geometry backTrimmedLane;
690  // update geometry
691  backTrimmedLane.updateGeometryShape(lanes.at(i)->getLaneShape(), -1, endPos, Position::INVALID, extraLastPosition);
692  // add sublane geometry
693  segmentGeometry.insertCustomSegment(AC, lane,
694  backTrimmedLane.getShape(),
695  backTrimmedLane.getShapeRotations(),
696  backTrimmedLane.getShapeLengths(), true);
697  } else {
698  // add entire lane geometry
699  segmentGeometry.insertLaneSegment(AC, lanes.at(i), true);
700  }
701  }
702  // now continue with connection
703  if ((i + 1) < (int)lanes.size()) {
704  // obtain next lane
705  const GNELane* nextLane = lanes.at(i + 1);
706  // check that next lane exist
707  if (lane->getLane2laneConnections().connectionsMap.count(nextLane) > 0) {
708  // add lane2laneConnection segment geometry
709  segmentGeometry.insertLane2LaneSegment(AC, lane, nextLane, true);
710  }
711  }
712  }
713  }
714  }
715 }
716 
717 
718 void
719 GNEGeometry::updateGeometricPath(GNEGeometry::SegmentGeometry& segmentGeometry, const GNEEdge* edge, double startPos, double endPos,
720  const Position& extraFirstPosition, const Position& extraLastPosition) {
721  // calculate depending if both from and to edges are the same
722  if ((segmentGeometry.size() == 1) && (segmentGeometry.front().edge == edge)) {
723  // filter start and end pos
724  adjustStartPosGeometricPath(startPos, segmentGeometry.front().lane, endPos, segmentGeometry.front().lane);
725  // check if we have to define a new custom Segment, or we can use the commonLane shape
726  if ((startPos != -1) || (endPos != -1) || (extraFirstPosition != Position::INVALID) || (extraLastPosition != Position::INVALID)) {
727  // declare a lane to be trimmed
728  Geometry trimmedLane;
729  // update geometry
730  trimmedLane.updateGeometryShape(segmentGeometry.front().lane->getLaneShape(), startPos, endPos, extraFirstPosition, extraLastPosition);
731  // add sublane geometry
732  segmentGeometry.updateCustomSegment(0,
733  trimmedLane.getShape(),
734  trimmedLane.getShapeRotations(),
735  trimmedLane.getShapeLengths());
736  }
737  } else {
738  // declare a vector to save segments to update
739  std::vector<GNEGeometry::SegmentGeometry::SegmentToUpdate> segmentsToUpdate;
740  // iterate over all segments
741  for (auto segment = segmentGeometry.begin(); segment != segmentGeometry.end(); segment++) {
742  if (segment->edge == edge) {
743  // obtain segment index
744  const int index = (int)(segment - segmentGeometry.begin());
745  // add SegmentToUpdate in vector
746  segmentsToUpdate.push_back(GNEGeometry::SegmentGeometry::SegmentToUpdate(index, segment->lane, nullptr));
747  // check if we have to add the next segment (it correspond to a lane2lane
748  if (((segment + 1) != segmentGeometry.end()) && (segment + 1)->junction) {
749  segmentsToUpdate.push_back(GNEGeometry::SegmentGeometry::SegmentToUpdate(index, segment->lane, (segment + 1)->lane));
750  }
751  }
752  }
753  // iterate over segments to update
754  for (const auto& segmentToUpdate : segmentsToUpdate) {
755  // first check that lane shape isn't empty
756  if (segmentToUpdate.lane->getLaneShape().size() > 0) {
757  // check if first or last lane must be splitted
758  if ((segmentToUpdate.index == 0) && (startPos != -1)) {
759  // filter start position
760  adjustStartPosGeometricPath(startPos, segmentToUpdate.lane, endPos, nullptr);
761  // declare a lane to be trimmed
762  Geometry frontTrimmedLane;
763  // update geometry
764  frontTrimmedLane.updateGeometryShape(segmentToUpdate.lane->getLaneShape(), startPos, -1, extraFirstPosition, Position::INVALID);
765  // update segment
766  segmentGeometry.updateCustomSegment(segmentToUpdate.index,
767  frontTrimmedLane.getShape(),
768  frontTrimmedLane.getShapeRotations(),
769  frontTrimmedLane.getShapeLengths());
770  } else if ((segmentToUpdate.index == (segmentGeometry.size() - 1)) && (endPos != -1)) {
771  // filter end position
772  adjustStartPosGeometricPath(startPos, nullptr, endPos, segmentToUpdate.lane);
773  // declare a lane to be trimmed
774  Geometry backTrimmedLane;
775  // update geometry
776  backTrimmedLane.updateGeometryShape(segmentToUpdate.lane->getLaneShape(), -1, endPos, Position::INVALID, extraLastPosition);
777  // update segment
778  segmentGeometry.updateCustomSegment(segmentToUpdate.index,
779  backTrimmedLane.getShape(),
780  backTrimmedLane.getShapeRotations(),
781  backTrimmedLane.getShapeLengths());
782  }
783  }
784  // check that next lane exist
785  if (segmentToUpdate.lane->getLane2laneConnections().connectionsMap.count(segmentToUpdate.nextLane) > 0) {
786  // update lane2laneConnection shape
787  segmentGeometry.updateLane2LaneSegment(segmentToUpdate.index, segmentToUpdate.lane, segmentToUpdate.nextLane);
788  }
789  }
790  }
791 }
792 
793 
794 void
795 GNEGeometry::drawGeometry(const GNEViewNet* viewNet, const Geometry& geometry, const double width) {
796  // first check if we're in draw for selecting cliking mode
798  // obtain mouse Position
799  const Position mousePosition = viewNet->getPositionInformation();
800  // obtain position over lane relative to mouse position
801  const Position posOverLane = geometry.getShape().positionAtOffset2D(geometry.getShape().nearest_offset_to_point2D(mousePosition));
802  // if mouse is over segment
803  if (posOverLane.distanceSquaredTo2D(mousePosition) <= (width * width)) {
804  // push matrix
805  glPushMatrix();
806  // translate to position over lane
807  glTranslated(posOverLane.x(), posOverLane.y(), 0);
808  // Draw circle
810  // pop draw matrix
811  glPopMatrix();
812  }
813  } else {
814  GLHelper::drawBoxLines(geometry.getShape(), geometry.getShapeRotations(), geometry.getShapeLengths(), width);
815  }
816 }
817 
818 
819 void
820 GNEGeometry::drawLaneGeometry(const GNEViewNet* viewNet, const PositionVector& shape, const std::vector<double>& rotations,
821  const std::vector<double>& lengths, const std::vector<RGBColor>& colors, double width) {
822  // first check if we're in draw for selecting cliking mode
824  // obtain mouse Position
825  const Position mousePosition = viewNet->getPositionInformation();
826  // obtain position over lane relative to mouse position
827  const Position posOverLane = shape.positionAtOffset2D(shape.nearest_offset_to_point2D(mousePosition));
828  // if mouse is over segment
829  if (posOverLane.distanceSquaredTo2D(mousePosition) <= (width * width)) {
830  // push matrix
831  glPushMatrix();
832  // translate to position over lane
833  glTranslated(posOverLane.x(), posOverLane.y(), 0);
834  // Draw circle
836  // pop draw matrix
837  glPopMatrix();
838  }
839  } else if (colors.size() > 0) {
840  // draw box lines with own colors
841  GLHelper::drawBoxLines(shape, rotations, lengths, colors, width);
842  } else {
843  // draw box lines with current color
844  GLHelper::drawBoxLines(shape, rotations, lengths, width);
845  }
846 }
847 
848 
849 void
850 GNEGeometry::drawSegmentGeometry(const GNEViewNet* viewNet, const SegmentGeometry::Segment& segment, const double width) {
851  // first check if we're in draw for selecting mode
853  // obtain mouse Position
854  const Position mousePosition = viewNet->getPositionInformation();
855  // obtain position over lane relative to mouse position
856  const Position posOverLane = segment.getShape().positionAtOffset2D(segment.getShape().nearest_offset_to_point2D(mousePosition));
857  // if mouse is over segment
858  if (posOverLane.distanceSquaredTo2D(mousePosition) <= (width * width)) {
859  // push matrix
860  glPushMatrix();
861  // translate to position over lane
862  glTranslated(posOverLane.x(), posOverLane.y(), 0);
863  // Draw circle
865  // pop draw matrix
866  glPopMatrix();
867  }
868  } else {
869  // draw a boxline as usual
870  GLHelper::drawBoxLines(segment.getShape(), segment.getShapeRotations(), segment.getShapeLengths(), width);
871  }
872 }
873 
874 /****************************************************************************/
GNEGeometry::calculateLength
static double calculateLength(const Position &first, const Position &second)
return length between two points (used in geometric calculations)
Definition: GNEGeometry.cpp:555
GUIVisualizationSettings::drawForPositionSelection
bool drawForPositionSelection
whether drawing is performed for the purpose of selecting objects with a single click
Definition: GUIVisualizationSettings.h:644
SUMOVehicleClass
SUMOVehicleClass
Definition of vehicle classes to differ between different lane usage and authority types.
Definition: SUMOVehicleClass.h:133
GNEGeometry::Lane2laneConnection::Lane2laneConnection
Lane2laneConnection(const GNELane *originLane)
constructor
Definition: GNEGeometry.cpp:395
GNEAdditional
An Element which don't belongs to GNENet but has influency in the simulation.
Definition: GNEAdditional.h:48
GNEAdditional.h
GNEGeometry::calculateEdgeGeometricPath
static void calculateEdgeGeometricPath(const GNEAttributeCarrier *AC, GNEGeometry::SegmentGeometry &segmentGeometry, const std::vector< GNEEdge * > &edges, const SUMOVehicleClass vClass, GNELane *fromLane, GNELane *toLane, double startPos=-1, double endPos=-1, const Position &extraFirstPosition=Position::INVALID, const Position &extraLastPosition=Position::INVALID)
calculate route between edges
Definition: GNEGeometry.cpp:591
GNEGeometry::SegmentGeometry::myShapeSegments
std::vector< Segment > myShapeSegments
vector of segments that constitutes the shape
Definition: GNEGeometry.h:248
GNEGeometry::Geometry::updateGeometryShape
void updateGeometryShape(const PositionVector &shape, double startPos=-1, double endPos=-1, const Position &extraFirstPosition=Position::INVALID, const Position &extraLastPosition=Position::INVALID)
update geometry shape
Definition: GNEGeometry.cpp:48
GNEGeometry::drawSegmentGeometry
static void drawSegmentGeometry(const GNEViewNet *viewNet, const SegmentGeometry::Segment &segment, const double width)
draw geometry segment
Definition: GNEGeometry.cpp:850
Position::INVALID
static const Position INVALID
used to indicate that a position is valid
Definition: Position.h:284
GLHelper::drawBoxLines
static void drawBoxLines(const PositionVector &geom, const std::vector< double > &rots, const std::vector< double > &lengths, double width, int cornerDetail=0, double offset=0)
Draws thick lines.
Definition: GLHelper.cpp:182
GNEGeometry::Geometry::getShapeLengths
const std::vector< double > & getShapeLengths() const
The lengths of the single shape parts.
Definition: GNEGeometry.cpp:159
GNEGeometry::ParentConnections::ParentConnections
ParentConnections(GNEHierarchicalParentElements *hierarchicalElement)
constructor
Definition: GNEGeometry.cpp:434
GNEGeometry::SegmentGeometry::insertLaneSegment
void insertLaneSegment(const GNEAttributeCarrier *AC, const GNELane *lane, const bool valid)
insert entire lane segment (used to avoid unnecessary calculation in calculatePartialShapeRotationsAn...
Definition: GNEGeometry.cpp:280
GNEGeometry::SegmentGeometry::getFirstRotation
double getFirstRotation() const
get first rotation (or Invalid position if segments are empty)
Definition: GNEGeometry.cpp:343
GNEGeometry::Geometry::updateGeometryPosition
void updateGeometryPosition(const GNELane *lane, const double posOverLane)
update position and rotation
Definition: GNEGeometry.cpp:100
GNEGeometry::drawLaneGeometry
static void drawLaneGeometry(const GNEViewNet *viewNet, const PositionVector &shape, const std::vector< double > &rotations, const std::vector< double > &lengths, const std::vector< RGBColor > &colors, double width)
draw lane geometry (use their own function due colors)
Definition: GNEGeometry.cpp:820
GNEGeometry::SegmentGeometry::clearSegmentGeometry
void clearSegmentGeometry()
clear element geometry
Definition: GNEGeometry.cpp:317
GNEGeometry::Geometry::calculateShapeRotationsAndLengths
void calculateShapeRotationsAndLengths()
calculate shape rotations and lengths
Definition: GNEGeometry.cpp:165
NBNode::computeSmoothShape
PositionVector computeSmoothShape(const PositionVector &begShape, const PositionVector &endShape, int numPoints, bool isTurnaround, double extrapolateBeg, double extrapolateEnd, NBNode *recordError=0, int shapeFlag=0) const
Compute a smooth curve between the given geometries.
Definition: NBNode.cpp:506
GNEGeometry::SegmentGeometry::insertLane2LaneSegment
void insertLane2LaneSegment(const GNEAttributeCarrier *AC, const GNELane *currentLane, const GNELane *nextLane, const bool valid)
insert entire lane2lane segment (used to avoid unnecessary calculation in calculatePartialShapeRotati...
Definition: GNEGeometry.cpp:295
GNEGeometry::SegmentGeometry::getLastPosition
const Position & getLastPosition() const
get first position (or Invalid position if segments are empty)
Definition: GNEGeometry.cpp:333
GNEViewNet
Definition: GNEViewNet.h:42
PositionVector::length
double length() const
Returns the length.
Definition: PositionVector.cpp:484
GUIVisualizationColorSettings::childConnections
static const RGBColor childConnections
color for child connections between parents and child elements
Definition: GUIVisualizationSettings.h:162
GLHelper.h
GNEGeometry::SegmentGeometry::Segment::Segment
Segment(const GNEAttributeCarrier *_AC, const GNELane *_lane, const bool _valid)
parameter constructor for lanes (geometry will be taked from lane)
Definition: GNEGeometry.cpp:188
GNEGeometry::SegmentGeometry::updateLane2LaneSegment
void updateLane2LaneSegment(const int segmentIndex, const GNELane *lane, const GNELane *nextLane)
update lane2Lane segment (used to avoid unnecessary calculation in calculatePartialShapeRotationsAndL...
Definition: GNEGeometry.cpp:308
PositionVector
A list of positions.
Definition: PositionVector.h:45
GNEGeometry::Geometry::Geometry
Geometry()
constructor
Definition: GNEGeometry.cpp:41
GLHelper::setColor
static void setColor(const RGBColor &c)
Sets the gl-color to this value.
Definition: GLHelper.cpp:621
NBEdge
The representation of a single edge during network building.
Definition: NBEdge.h:91
GNEGeometry::SegmentGeometry::Segment::edge
const GNEEdge * edge
edge
Definition: GNEGeometry.h:146
INVALID
#define INVALID
Definition: MSDevice_SSM.cpp:70
GNEJunction.h
GNEGeometry::SegmentGeometry::insertCustomSegment
void insertCustomSegment(const GNEAttributeCarrier *AC, const GNELane *lane, const PositionVector &laneShape, const std::vector< double > &laneShapeRotations, const std::vector< double > &laneShapeLengths, const bool valid)
insert custom segment
Definition: GNEGeometry.cpp:287
GUIGlObjectType
GUIGlObjectType
Definition: GUIGlObjectTypes.h:39
GNEEdge
A road/street connecting two junctions (netedit-version)
Definition: GNEEdge.h:51
GNEGeometry::SegmentGeometry::Segment::getShapeLengths
const std::vector< double > & getShapeLengths() const
get lane/lane2lane shape lengths
Definition: GNEGeometry.cpp:264
GLHelper::drawFilledCircle
static void drawFilledCircle(double width, int steps=8)
Draws a filled circle around (0,0)
Definition: GLHelper.cpp:348
PositionVector::nearest_offset_to_point2D
double nearest_offset_to_point2D(const Position &p, bool perpendicular=true) const
return the nearest offest to point 2D
Definition: PositionVector.cpp:817
NBEdge::getToNode
NBNode * getToNode() const
Returns the destination node of the edge.
Definition: NBEdge.h:498
GNEGeometry::SegmentGeometry::SegmentToUpdate::SegmentToUpdate
SegmentToUpdate(const int _index, const GNELane *_lane, const GNELane *_nextLane)
constructor
Definition: GNEGeometry.cpp:236
GNEGeometry::SegmentGeometry
struct for pack all variables related with geometry of elemements divided in segments
Definition: GNEGeometry.h:116
GNEAttributeCarrier::getTagProperty
const TagProperties & getTagProperty() const
get Tag Property assigned to this object
Definition: GNEAttributeCarrier.cpp:1273
GNEGeometry::Geometry::getShape
const PositionVector & getShape() const
The shape of the additional element.
Definition: GNEGeometry.cpp:147
GNELane::getLaneShape
const PositionVector & getLaneShape() const
Definition: GNELane.cpp:86
GNEAdditional::getAdditionalGeometry
const GNEGeometry::Geometry & getAdditionalGeometry() const
obtain additional geometry
Definition: GNEAdditional.cpp:106
GUISUMOAbstractView::getVisualisationSettings
GUIVisualizationSettings * getVisualisationSettings() const
get visualitation settings
Definition: GUISUMOAbstractView.cpp:236
GNEGeometry::SegmentGeometry::Segment::update
void update(const PositionVector &shape, const std::vector< double > &shapeRotations, const std::vector< double > &shapeLengths)
update segment
Definition: GNEGeometry.cpp:229
GNEViewNet.h
GNELane::getLane2laneConnections
const GNEGeometry::Lane2laneConnection & getLane2laneConnections() const
get Lane2laneConnection struct
Definition: GNELane.cpp:815
PositionVector::positionAtOffset
Position positionAtOffset(double pos, double lateralOffset=0) const
Returns the position at the given length.
Definition: PositionVector.cpp:248
PositionVector::rotationDegreeAtOffset
double rotationDegreeAtOffset(double pos) const
Returns the rotation at the given length.
Definition: PositionVector.cpp:319
Boundary
A class that stores a 2D geometrical boundary.
Definition: Boundary.h:41
NBEdge::getNumLanes
int getNumLanes() const
Returns the number of lanes.
Definition: NBEdge.h:477
GNEGeometry::Lane2laneConnection::updateLane2laneConnection
void updateLane2laneConnection()
update
Definition: GNEGeometry.cpp:401
GNEGeometry::Geometry::getRotation
double getRotation() const
get rotation
Definition: GNEGeometry.cpp:137
GNEGeometry::drawGeometry
static void drawGeometry(const GNEViewNet *viewNet, const Geometry &geometry, const double width)
draw geometry
Definition: GNEGeometry.cpp:795
ProcessError
Definition: UtilExceptions.h:39
GNEGeometry::ParentConnections::update
void update()
update Connection's geometry
Definition: GNEGeometry.cpp:439
GNEGeometry::SegmentGeometry::begin
std::vector< Segment >::const_iterator begin() const
begin iterator
Definition: GNEGeometry.cpp:363
Position
A point in 2D or 3D with translation and scaling methods.
Definition: Position.h:38
Position::x
double x() const
Returns the x-position.
Definition: Position.h:56
Boundary::add
void add(double x, double y, double z=0)
Makes the boundary include the given coordinate.
Definition: Boundary.cpp:78
GNEEdge.h
GNEGeometry::SegmentGeometry::updateCustomSegment
void updateCustomSegment(const int segmentIndex, const PositionVector &newLaneShape, const std::vector< double > &newLaneShapeRotations, const std::vector< double > &newLaneShapeLengths)
update custom segment
Definition: GNEGeometry.cpp:302
GNEGeometry::updateGeometricPath
static void updateGeometricPath(GNEGeometry::SegmentGeometry &segmentGeometry, const GNEEdge *edge, double startPos=-1, double endPos=-1, const Position &extraFirstPosition=Position::INVALID, const Position &extraLastPosition=Position::INVALID)
calculate route between edges
Definition: GNEGeometry.cpp:719
GLHelper::drawLine
static void drawLine(const Position &beg, double rot, double visLength)
Draws a thin line.
Definition: GLHelper.cpp:274
GNEGeometry::Geometry
struct for pack all variables related with geometry of stop
Definition: GNEGeometry.h:56
GNEGeometry::SegmentGeometry::getBoxBoundary
Boundary getBoxBoundary() const
Returns a boundary enclosing all segments.
Definition: GNEGeometry.cpp:353
GUISUMOAbstractView::getPositionInformation
Position getPositionInformation() const
Returns the cursor's x/y position within the network.
Definition: GUISUMOAbstractView.cpp:190
GNEGeometry::SegmentGeometry::getFirstPosition
const Position & getFirstPosition() const
get first position (or Invalid position if segments are empty)
Definition: GNEGeometry.cpp:324
GNELane.h
PositionVector::splitAt
std::pair< PositionVector, PositionVector > splitAt(double where, bool use2D=false) const
Returns the two lists made when this list vector is splitted at the given point.
Definition: PositionVector.cpp:552
Position::distanceSquaredTo2D
double distanceSquaredTo2D(const Position &p2) const
returns the square of the distance to another position (Only using x and y positions)
Definition: Position.h:248
GNEGeometry::Geometry::getPosition
const Position & getPosition() const
get Position
Definition: GNEGeometry.cpp:127
GUIVisualizationSettings::getCircleResolution
int getCircleResolution() const
function to calculate circle resolution for all circles drawn in drawGL(...) functions
Definition: GUIVisualizationSettings.cpp:1679
Position::distanceTo2D
double distanceTo2D(const Position &p2) const
returns the euclidean distance in the x-y-plane
Definition: Position.h:243
GNEGeometry::SegmentGeometry::Segment::getShapeRotations
const std::vector< double > & getShapeRotations() const
get lane/lane2lane shape rotations
Definition: GNEGeometry.cpp:254
GLIncludes.h
NBEdge::getLaneShape
const PositionVector & getLaneShape(int i) const
Returns the shape of the nth lane.
Definition: NBEdge.cpp:879
NBNode::getShape
const PositionVector & getShape() const
retrieve the junction shape
Definition: NBNode.cpp:2140
GNEGeometry.h
GNEGeometry::SegmentGeometry::Segment
struct used for represent segments of element geometry
Definition: GNEGeometry.h:119
Position::y
double y() const
Returns the y-position.
Definition: Position.h:61
PositionVector::positionAtOffset2D
Position positionAtOffset2D(double pos, double lateralOffset=0) const
Returns the position at the given length.
Definition: PositionVector.cpp:273
M_PI
#define M_PI
Definition: odrSpiral.cpp:40
GNEGeometry::SegmentGeometry::SegmentGeometry
SegmentGeometry()
constructor
Definition: GNEGeometry.cpp:276
GNEHierarchicalParentElements
An special type of Attribute carrier that owns hierarchical elements.
Definition: GNEHierarchicalParentElements.h:49
GNEGeometry::calculateLaneGeometricPath
static void calculateLaneGeometricPath(const GNEAttributeCarrier *AC, GNEGeometry::SegmentGeometry &segmentGeometry, const std::vector< GNELane * > &lanes, double startPos=-1, double endPos=-1, const Position &extraFirstPosition=Position::INVALID, const Position &extraLastPosition=Position::INVALID)
calculate route between lanes
Definition: GNEGeometry.cpp:640
GNEGeometry::SegmentGeometry::front
const Segment & front() const
front segment
Definition: GNEGeometry.cpp:375
GNEGeometry::SegmentGeometry::Segment::lane
const GNELane * lane
lane
Definition: GNEGeometry.h:149
GNEGeometry::SegmentGeometry::size
int size() const
number of segments
Definition: GNEGeometry.cpp:387
GNEGeometry::Geometry::getShapeRotations
const std::vector< double > & getShapeRotations() const
The rotations of the single shape parts.
Definition: GNEGeometry.cpp:153
GNEGeometry::adjustStartPosGeometricPath
static void adjustStartPosGeometricPath(double &startPos, const GNELane *startLane, double &endPos, const GNELane *endLane)
adjust start and end positions in geometric path
Definition: GNEGeometry.cpp:562
GNEGeometry::calculateRotation
static double calculateRotation(const Position &first, const Position &second)
return angle between two points (used in geometric calculations)
Definition: GNEGeometry.cpp:548
GNEAttributeCarrier::TagProperties::isRide
bool isRide() const
return true if tag correspond to a ride element
Definition: GNEAttributeCarrier.cpp:780
GUIVisualizationSettings
Stores the information about how to visualize structures.
Definition: GUIVisualizationSettings.h:345
GNEGeometry::SegmentGeometry::Segment::getShape
const PositionVector & getShape() const
get lane/lane2lane shape
Definition: GNEGeometry.cpp:244
PositionVector::area
double area() const
Returns the area (0 for non-closed)
Definition: PositionVector.cpp:510
POSITION_EPS
#define POSITION_EPS
Definition: config.h:172
GNELane
This lane is powered by an underlying GNEEdge and basically knows how to draw itself.
Definition: GNELane.h:45
GNEGeometry::SegmentGeometry::SegmentToUpdate
struct used for represent segments that must be updated
Definition: GNEGeometry.h:178
GNEGeometry::Lane2laneConnection::connectionsMap
std::map< const GNELane *, Geometry > connectionsMap
connection shape
Definition: GNEGeometry.h:264
GNEAttributeCarrier
Definition: GNEAttributeCarrier.h:54
GNEGeometry::SegmentGeometry::end
std::vector< Segment >::const_iterator end() const
end iterator
Definition: GNEGeometry.cpp:369
GNEGeometry::SegmentGeometry::back
const Segment & back() const
back segment
Definition: GNEGeometry.cpp:381
GNEGeometry::Geometry::updateGeometry
void updateGeometry(const GNEAdditional *additional)
update geometry (using geometry of another additional)
Definition: GNEGeometry.cpp:118
NBEdge::getTurnDestination
NBEdge * getTurnDestination(bool possibleDestination=false) const
Definition: NBEdge.cpp:3084
GNEGeometry::ParentConnections::draw
void draw(const GUIVisualizationSettings &s, const GUIGlObjectType parentType) const
draw connections between Parent and childrens
Definition: GNEGeometry.cpp:524