42 #define DEBUGCOND true
44 #define MIN_TURN_DIAMETER 2.0
56 if (!oc.
isSet(
"opendrive-output")) {
61 const bool origNames = oc.
getBool(
"output.original-names");
62 const bool lefthand = oc.
getBool(
"lefthand");
63 const double straightThresh =
DEG2RAD(oc.
getFloat(
"opendrive-output.straight-threshold"));
66 int edgeID = nc.
size() * 10;
72 time_t now = time(
nullptr);
73 std::string dstr(ctime(&now));
81 device.
writeAttr(
"date", dstr.substr(0, dstr.length() - 1));
111 for (std::map<std::string, NBEdge*>::const_iterator i = ec.
begin(); i != ec.
end(); ++i) {
112 const NBEdge* e = (*i).second;
117 fromNodeID, toNodeID,
118 origNames, straightThresh,
125 for (std::map<std::string, NBNode*>::const_iterator i = nc.
begin(); i != nc.
end(); ++i) {
127 int connectionID = 0;
128 const int nID =
getID(n->
getID(), nodeMap, nodeID);
130 junctionOSS <<
" <junction name=\"" << n->
getID() <<
"\" id=\"" << nID <<
"\">\n";
132 std::vector<NBEdge*> incoming = (*i).second->getIncomingEdges();
134 std::reverse(incoming.begin(), incoming.end());
136 for (
NBEdge* inEdge : incoming) {
137 std::string centerMark =
"none";
138 const int inEdgeID =
getID(inEdge->getID(), edgeMap, edgeID);
140 const NBEdge* outEdge =
nullptr;
141 bool isOuterEdge =
true;
142 int lastFromLane = -1;
143 std::vector<NBEdge::Connection> parallel;
144 std::vector<NBEdge::Connection> connections = inEdge->
getConnections();
146 std::reverse(connections.begin(), connections.end());
149 assert(c.toEdge != 0);
150 if (outEdge != c.toEdge || c.fromLane == lastFromLane) {
151 if (outEdge !=
nullptr) {
156 getID(parallel.back().getInternalLaneID(), edgeMap, edgeID),
160 parallel, isOuterEdge, straightThresh, centerMark);
166 lastFromLane = c.fromLane;
167 parallel.push_back(c);
172 if (!parallel.empty()) {
173 if (!lefthand && (n->
geometryLike() || inEdge->isTurningDirectionAt(outEdge))) {
174 centerMark =
"solid";
177 getID(parallel.back().getInternalLaneID(), edgeMap, edgeID),
181 parallel, isOuterEdge, straightThresh, centerMark);
186 junctionOSS <<
" </junction>\n";
193 for (std::map<std::string, NBNode*>::const_iterator i = nc.
begin(); i != nc.
end(); ++i) {
197 int numConnections = 0;
198 for (std::vector<NBEdge*>::const_iterator j = incoming.begin(); j != incoming.end(); ++j) {
199 numConnections += (int)((*j)->getConnections().size());
201 if (numConnections == 0) {
204 for (std::vector<NBEdge*>::const_iterator j = incoming.begin(); j != incoming.end(); ++j) {
205 const NBEdge* inEdge = *j;
206 const std::vector<NBEdge::Connection>& elv = inEdge->
getConnections();
207 for (std::vector<NBEdge::Connection>::const_iterator k = elv.begin(); k != elv.end(); ++k) {
210 if (outEdge ==
nullptr) {
224 int edgeID,
int fromNodeID,
int toNodeID,
225 const bool origNames,
226 const double straightThresh,
235 planViewOSS.
openTag(
"planView");
237 const std::vector<NBEdge::Lane>& lanes = e->
getLanes();
239 #ifdef DEBUG_SMOOTH_GEOM
241 std::cout <<
"write planview for edge " << e->
getID() <<
"\n";
267 device.
writeAttr(
"elementType",
"junction");
268 device.
writeAttr(
"elementId", fromNodeID);
273 device.
writeAttr(
"elementType",
"junction");
282 device <<
" <lateralProfile/>\n";
283 device <<
" <lanes>\n";
284 device <<
" <laneSection s=\"0\">\n";
287 device <<
" <right>\n";
290 if (laneType ==
"") {
293 device <<
" <lane id=\"-" << e->
getNumLanes() - j <<
"\" type=\"" << laneType <<
"\" level=\"true\">\n";
294 device <<
" <link/>\n";
302 device <<
" <width sOffset=\"0\" a=\"" << e->
getLaneWidth(j) <<
"\" b=\"0\" c=\"0\" d=\"0\"/>\n";
303 std::string markType =
"broken";
314 device <<
" <roadMark sOffset=\"0\" type=\"" << markType <<
"\" weight=\"standard\" color=\"standard\" width=\"0.13\"/>\n";
315 device <<
" <speed sOffset=\"0\" max=\"" << lanes[j].speed <<
"\"/>\n";
316 device <<
" </lane>\n";
318 device <<
" </right>\n";
319 device <<
" </laneSection>\n";
320 device <<
" </lanes>\n";
322 device <<
" <signals/>\n";
324 device <<
" <userData code=\"sumoId\" value=\"" << e->
getID() <<
"\"/>\n";
334 if (outEdge !=
nullptr
338 || parallel.front().fromLane != 0
339 || parallel.front().toLane != 0)) {
341 parallel.front().vmax = (inEdge->
getLanes()[0].speed + outEdge->
getLanes()[0].speed) / (
double) 2.0;
348 int edgeID,
int inEdgeID,
int outEdgeID,
350 const std::vector<NBEdge::Connection>& parallel,
351 const bool isOuterEdge,
352 const double straightThresh,
353 const std::string& centerMark) {
354 assert(parallel.size() != 0);
362 double laneOffset = 0;
364 fallBackShape.push_back(begShape.back());
365 fallBackShape.push_back(endShape.front());
369 if (init.size() == 0) {
374 }
else if (length <= NUMERICAL_EPS) {
380 if (init.size() != 0) {
390 junctionDevice <<
" <connection id=\"" << connectionID <<
"\" incomingRoad=\"" << inEdgeID <<
"\" connectingRoad=\"" << edgeID <<
"\" contactPoint=\"start\">\n";
406 device.
writeAttr(
"elementId", outEdgeID);
407 device.
writeAttr(
"contactPoint",
"start");
415 #ifdef DEBUG_SMOOTH_GEOM
417 std::cout <<
"write planview for internal edge " << cLeft.
id <<
" init=" << init <<
" fallback=" << fallBackShape
418 <<
" begShape=" << begShape <<
" endShape=" << endShape
422 if (init.size() == 0) {
430 device <<
" <lateralProfile/>\n";
431 device <<
" <lanes>\n";
432 if (laneOffset != 0) {
433 device <<
" <laneOffset s=\"0\" a=\"" << laneOffset <<
"\" b=\"0\" c=\"0\" d=\"0\"/>\n";
435 device <<
" <laneSection s=\"0\">\n";
437 device <<
" <right>\n";
438 int toIndexInternal = 0;
439 for (
int j = (
int)parallel.size(); --j >= 0;) {
445 device <<
" <link>\n";
446 device <<
" <predecessor id=\"" << fromIndex <<
"\"/>\n";
447 device <<
" <successor id=\"" << toIndex <<
"\"/>\n";
448 device <<
" </link>\n";
449 device <<
" <width sOffset=\"0\" a=\"" << outEdge->
getLaneWidth(c.
toLane) <<
"\" b=\"0\" c=\"0\" d=\"0\"/>\n";
450 std::string markType =
"broken";
456 }
else if (isOuterEdge && j > 0
471 device <<
" <roadMark sOffset=\"0\" type=\"" << markType <<
"\" weight=\"standard\" color=\"standard\" width=\"0.13\"/>\n";
472 device <<
" <speed sOffset=\"0\" max=\"" << c.
vmax <<
"\"/>\n";
473 device <<
" </lane>\n";
475 junctionDevice <<
" <laneLink from=\"" << fromIndex <<
"\" to=\"" << toIndexInternal <<
"\"/>\n";
478 device <<
" </right>\n";
479 device <<
" </laneSection>\n";
480 device <<
" </lanes>\n";
481 device <<
" <objects/>\n";
482 device <<
" <signals/>\n";
484 junctionDevice <<
" </connection>\n";
492 for (
int j = 0; j < (int)shape.size() - 1; ++j) {
505 elevationDevice <<
" <elevation s=\"" << offset <<
"\" a=\"" << p.
z() <<
"\" b=\"" << (p2.
z() - p.
z()) /
MAX2(POSITION_EPS, length) <<
"\" c=\"0\" d=\"0\"/>\n";
514 device <<
" <center>\n";
515 device <<
" <lane id=\"0\" type=\"none\" level=\"true\">\n";
516 device <<
" <link/>\n";
517 device <<
" <roadMark sOffset=\"0\" type=\"" << mark <<
"\" weight=\"standard\" color=\"standard\" width=\"" << markWidth <<
"\"/>\n";
518 device <<
" </lane>\n";
519 device <<
" </center>\n";
526 return map.
get(origID);
528 map.
insert(origID, lastID++);
535 switch (permissions) {
555 if (permissions ==
SVCAll) {
572 if (laneIndex == -1) {
574 laneIndex = lefthand ? 0 : (int)edge->
getNumLanes() - 1;
583 const int leftmost = lefthand ? 0 : (int)edge->
getNumLanes() - 1;
587 for (
int i = leftmost; i < laneIndex; i++) {
591 for (
int i = leftmost; i > laneIndex; i--) {
615 assert(init.size() == 3 || init.size() == 4);
618 length =
MAX2(POSITION_EPS, length);
626 init.
add(-p.
x(), -p.
y(), -p.
z());
630 double aU, bU, cU, dU;
631 double aV, bV, cV, dV;
632 double aZ, bZ, cZ, dZ;
635 if (init.size() == 3) {
638 bU = 2 * init[1].x() - 2 * init[0].x();
639 cU = init[0].x() - 2 * init[1].x() + init[2].x();
643 bV = 2 * init[1].y() - 2 * init[0].y();
644 cV = init[0].y() - 2 * init[1].y() + init[2].y();
649 bZ = (2 * initZ[1].z() - 2 * initZ[0].z()) / length;
650 cZ = (initZ[0].z() - 2 * initZ[1].z() + initZ[2].z()) / (length * length);
656 bU = 3 * init[1].x() - 3 * init[0].x();
657 cU = 3 * init[0].x() - 6 * init[1].x() + 3 * init[2].x();
658 dU = -init[0].x() + 3 * init[1].x() - 3 * init[2].x() + init[3].x();
661 bV = 3 * init[1].y() - 3 * init[0].y();
662 cV = 3 * init[0].y() - 6 * init[1].y() + 3 * init[2].y();
663 dV = -init[0].y() + 3 * init[1].y() - 3 * init[2].y() + init[3].y();
667 bZ = (3 * initZ[1].z() - 3 * initZ[0].z()) / length;
668 cZ = (3 * initZ[0].z() - 6 * initZ[1].z() + 3 * initZ[2].z()) / (length * length);
669 dZ = (-initZ[0].z() + 3 * initZ[1].z() - 3 * initZ[2].z() + initZ[3].z()) / (length * length * length);
692 elevationDevice.
openTag(
"elevation");
700 return offset + length;
706 #ifdef DEBUG_SMOOTH_GEOM
708 std::cout <<
"writeGeomSmooth\n n=" << shape.size() <<
" shape=" <<
toString(shape) <<
"\n";
712 const double longThresh = speed;
713 const double curveCutout = longThresh / 2;
715 assert(longThresh >= 2 * curveCutout);
716 assert(shape.size() > 2);
720 double maxAngleDiff = 0;
722 for (
int j = 1; j < (int)shape.size() - 1; ++j) {
730 maxAngleDiff =
MAX2(maxAngleDiff, dAngle);
731 #ifdef DEBUG_SMOOTH_GEOM
733 std::cout <<
" j=" << j <<
" dAngle=" <<
RAD2DEG(dAngle) <<
" length1=" << length1 <<
" length2=" << length2 <<
"\n";
736 if (dAngle > straightThresh
737 && (length1 > longThresh || j == 1)
738 && (length2 > longThresh || j == (
int)shape.size() - 2)) {
745 const int numPoints = (int)shape2.size();
746 #ifdef DEBUG_SMOOTH_GEOM
748 std::cout <<
" n=" << numPoints <<
" shape2=" <<
toString(shape2) <<
"\n";
752 if (maxAngleDiff < straightThresh) {
754 #ifdef DEBUG_SMOOTH_GEOM
756 std::cout <<
" special case: all lines. maxAngleDiff=" << maxAngleDiff <<
"\n";
764 for (
int j = 0; j < numPoints - 1; ++j) {
770 const double lineLength = line.
length2D();
771 if (lineLength >= longThresh) {
773 #ifdef DEBUG_SMOOTH_GEOM
775 std::cout <<
" writeLine=" <<
toString(line) <<
"\n";
782 if (j == 0 || j == numPoints - 2) {
785 begShape.
add(p0 - begShape.back());
786 }
else if (j == 1 || p0.
distanceTo2D(shape2[j - 1]) > longThresh) {
788 begShape.push_back(shape2[j - 1]);
789 begShape.push_back(p0);
792 begShape.push_back(shape2[j - 1]);
793 begShape.push_back(p1);
794 begShape.
add(p0 - begShape.back());
797 if (j == 0 || j == numPoints - 2) {
800 endShape.
add(p1 - endShape.front());
801 }
else if (j == numPoints - 3 || p1.
distanceTo2D(shape2[j + 2]) > longThresh) {
803 endShape.push_back(p1);
804 endShape.push_back(shape2[j + 2]);
807 endShape.push_back(p0);
808 endShape.push_back(shape2[j + 2]);
809 endShape.
add(p1 - endShape.front());
811 const double extrapolateLength =
MIN2((
double)25, lineLength / 4);
813 if (init.size() == 0) {
816 #ifdef DEBUG_SMOOTH_GEOM
818 std::cout <<
" writeLine lineLength=" << lineLength <<
" begShape" << j <<
"=" <<
toString(begShape) <<
" endShape" << j <<
"=" <<
toString(endShape) <<
" init" << j <<
"=" <<
toString(init) <<
"\n";
824 offset =
writeGeomPP3(device, elevationDevice, init, curveLength, offset);
825 #ifdef DEBUG_SMOOTH_GEOM
827 std::cout <<
" writeCurve lineLength=" << lineLength <<
" curveLength=" << curveLength <<
" begShape" << j <<
"=" <<
toString(begShape) <<
" endShape" << j <<
"=" <<
toString(endShape) <<
" init" << j <<
"=" <<
toString(init) <<
"\n";
842 double z = shape.size() == 0 ? 0 : shape[0].z();
843 for (
int i = 1; i < (int)shape.size(); ++i) {
844 if (fabs(shape[i].z() - z) > NUMERICAL_EPS) {
849 device <<
" <elevationProfile>\n";
851 device <<
" <elevation s=\"0\" a=\"" << z <<
"\" b=\"0\" c=\"0\" d=\"0\"/>\n";
855 device <<
" </elevationProfile>\n";
865 assert(shape0.size() >= 2);
869 stopLine.push_back(to);
872 for (
int lane = 1; lane < e->
getNumLanes(); ++lane) {
874 if (dist > NUMERICAL_EPS) {
890 WRITE_WARNING(
"Road object polygon '" +
id +
"' not found for edge '" + e->
getID() +
"'");
891 }
else if (p->
getShape().size() != 4) {
899 const double absAngle = sideline.
angleAt2D(0);
900 const double length = sideline.
length2D();
901 const double width = ortholine.
length2D();
904 WRITE_WARNING(
"Cannot map road object polygon '" +
id +
"' with center " +
toString(center) +
" onto edge '" + e->
getID() +
"'");
909 const double relAngle = absAngle - edgeAngle;
936 device <<
" <objects/>\n";
#define WRITE_WARNING(msg)
const SVCPermissions SVCAll
all VClasses are allowed
bool isRailway(SVCPermissions permissions)
Returns whether an edge with the given permission is a railway edge.
@ SVC_RAIL
vehicle is a not electrified rail
@ SVC_PASSENGER
vehicle is a passenger car (a "normal" car)
@ SVC_BICYCLE
vehicle is a bicycle
@ SVC_RAIL_FAST
vehicle that is allowed to drive on high-speed rail tracks
@ SVC_RAIL_ELECTRIC
rail vehicle that requires electrified tracks
@ SVC_RAIL_URBAN
vehicle is a city rail
@ SVC_TRAM
vehicle is a light rail
@ SVC_PEDESTRIAN
pedestrian
int SVCPermissions
bitset where each bit declares whether a certain SVC may use this edge/lane
LinkDirection
The different directions a link between two lanes may take (or a stream between two edges)....
@ PARTLEFT
The link is a partial left direction.
@ RIGHT
The link is a (hard) right direction.
@ LEFT
The link is a (hard) left direction.
@ PARTRIGHT
The link is a partial right direction.
int gPrecision
the precision for floating point outputs
std::string toString(const T &t, std::streamsize accuracy=gPrecision)
A class that stores a 2D geometrical boundary.
double ymin() const
Returns minimum y-coordinate.
double xmin() const
Returns minimum x-coordinate.
double ymax() const
Returns maximum y-coordinate.
double xmax() const
Returns maximum x-coordinate.
static methods for processing the coordinates conversion for the current net
const std::string & getProjString() const
Returns the original projection definition.
static const GeoConvHelper & getFinal()
the coordinate transformation for writing the location element and for tracking the original coordina...
const Position getOffsetBase() const
Returns the network base.
bool usingGeoProjection() const
Returns whether a transformation from geo to metric coordinates will be performed.
const Boundary & getConvBoundary() const
Returns the converted boundary.
static const double INVALID_OFFSET
a value to signify offsets outside the range of [0, Line.length()]
static double angleDiff(const double angle1, const double angle2)
Returns the difference of the second angle to the first angle in radiants.
Storage for edges, including some functionality operating on multiple edges.
std::map< std::string, NBEdge * >::const_iterator begin() const
Returns the pointer to the begin of the stored edges.
std::map< std::string, NBEdge * >::const_iterator end() const
Returns the pointer to the end of the stored edges.
The representation of a single edge during network building.
SVCPermissions getPermissions(int lane=-1) const
get the union of allowed classes over all lanes or for a specific lane
double getLaneWidth() const
Returns the default width of lanes of this edge.
const std::string & getStreetName() const
Returns the street name of this edge.
const std::string & getID() const
const std::vector< NBEdge::Lane > & getLanes() const
Returns the lane definitions.
NBNode * getToNode() const
Returns the destination node of the edge.
double getSpeed() const
Returns the speed allowed on this edge.
bool isTurningDirectionAt(const NBEdge *const edge) const
Returns whether the given edge is the opposite direction to this edge.
int getNumLanes() const
Returns the number of lanes.
std::string getLaneID(int lane) const
get lane ID
const std::vector< Connection > & getConnections() const
Returns the connections.
const PositionVector & getLaneShape(int i) const
Returns the shape of the nth lane.
Lane & getLaneStruct(int lane)
NBNode * getFromNode() const
Returns the origin node of the edge.
EdgeVector getIncomingEdges() const
Returns the list of incoming edges unsorted.
Instance responsible for building networks.
ShapeContainer & getShapeCont()
NBEdgeCont & getEdgeCont()
NBNodeCont & getNodeCont()
Returns a reference to the node container.
Container for nodes during the netbuilding process.
std::map< std::string, NBNode * >::const_iterator begin() const
Returns the pointer to the begin of the stored nodes.
int size() const
Returns the number of nodes stored in this container.
std::map< std::string, NBNode * >::const_iterator end() const
Returns the pointer to the end of the stored nodes.
Represents a single node (junction) during network building.
LinkDirection getDirection(const NBEdge *const incoming, const NBEdge *const outgoing, bool leftHand=false) const
Returns the representation of the described stream's direction.
int numNormalConnections() const
return the number of lane-to-lane connections at this junction (excluding crossings)
const EdgeVector & getIncomingEdges() const
Returns this node's incoming edges (The edges which yield in this node)
bool geometryLike() const
whether this is structurally similar to a geometry node
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
static void addPedestrianConnection(const NBEdge *inEdge, const NBEdge *outEdge, std::vector< NBEdge::Connection > ¶llel)
static void checkLaneGeometries(const NBEdge *e)
check if the lane geometries are compatible with OpenDRIVE assumptions (colinear stop line)
static void writeEmptyCenterLane(OutputDevice &device, const std::string &mark, double markWidth)
static void writeElevationProfile(const PositionVector &shape, OutputDevice &device, const OutputDevice_String &elevationDevice)
static PositionVector getRightLaneBorder(const NBEdge *edge, int laneIndex=-1)
static void writeNormalEdge(OutputDevice &device, const NBEdge *e, int edgeID, int fromNodeID, int toNodeID, const bool origNames, const double straightThresh, const ShapeContainer &shc)
write normal edge to device
static std::string getLaneType(SVCPermissions permissions)
static bool writeGeomSmooth(const PositionVector &shape, double speed, OutputDevice &device, OutputDevice &elevationDevice, double straightThresh, double &length)
static void writeRoadObjects(OutputDevice &device, const NBEdge *e, const ShapeContainer &shc)
write road objects referenced as edge parameters
static PositionVector getLeftLaneBorder(const NBEdge *edge, int laneIndex=-1, double widthOffset=0)
get the left border of the given lane (the leftmost one by default)
static int writeInternalEdge(OutputDevice &device, OutputDevice &junctionDevice, const NBEdge *inEdge, int nodeID, int edgeID, int inEdgeID, int outEdgeID, int connectionID, const std::vector< NBEdge::Connection > ¶llel, const bool isOuterEdge, const double straightThresh, const std::string ¢erMark)
write internal edge to device, return next connectionID
static void writeNetwork(const OptionsCont &oc, NBNetBuilder &nb)
Writes the network into a openDRIVE-file.
static int getID(const std::string &origID, StringBijection< int > &map, int &lastID)
static double writeGeomPP3(OutputDevice &device, OutputDevice &elevationDevice, PositionVector init, double length, double offset=0)
write geometry as a single bezier curve (paramPoly3)
static double writeGeomLines(const PositionVector &shape, OutputDevice &device, OutputDevice &elevationDevice, double offset=0)
write geometry as sequence of lines (sumo style)
const std::string & getID() const
Returns the id.
T get(const std::string &id) const
Retrieves an item.
A storage for options typed value containers)
bool isSet(const std::string &name, bool failOnNonExistant=true) const
Returns the information whether the named option is set.
double getFloat(const std::string &name) const
Returns the double-value of the named option (only for Option_Float)
std::string getString(const std::string &name) const
Returns the string-value of the named option (only for Option_String)
bool getBool(const std::string &name) const
Returns the boolean-value of the named option (only for Option_Bool)
static OptionsCont & getOptions()
Retrieves the options.
An output device that encapsulates an ofstream.
std::string getString() const
Returns the current content as a string.
Static storage of an output device and its base (abstract) implementation.
OutputDevice & writePreformattedTag(const std::string &val)
writes a preformatted tag to the device but ensures that any pending tags are closed
void lf()
writes a line feed if applicable
void close()
Closes the device and removes it from the dictionary.
OutputDevice & openTag(const std::string &xmlElement)
Opens an XML tag.
static bool createDeviceByOption(const std::string &optionName, const std::string &rootElement="", const std::string &schemaFile="")
Creates the device using the output definition stored in the named option.
OutputDevice & writeAttr(const SumoXMLAttr attr, const T &val)
writes a named attribute
bool closeTag(const std::string &comment="")
Closes the most recently opened tag and optionally adds a comment.
void setPrecision(int precision=gPrecision)
Sets the precision or resets it to default.
static OutputDevice & getDevice(const std::string &name)
Returns the described OutputDevice.
virtual const std::string getParameter(const std::string &key, const std::string defaultValue="") const
Returns the value for a given key.
bool knowsParameter(const std::string &key) const
Returns whether the parameter is known.
A point in 2D or 3D with translation and scaling methods.
double distanceTo2D(const Position &p2) const
returns the euclidean distance in the x-y-plane
double x() const
Returns the x-position.
double z() const
Returns the z-position.
double angleTo2D(const Position &other) const
returns the angle in the plane of the vector pointing from here to the other position
double y() const
Returns the y-position.
double length2D() const
Returns the length.
void rotate2D(double angle)
Position getPolygonCenter() const
Returns the arithmetic of all corner points.
double rotationAtOffset(double pos) const
Returns the rotation at the given length.
void add(double xoff, double yoff, double zoff)
static Position sideOffset(const Position &beg, const Position &end, const double amount)
get a side position of position vector using a offset
double distance2D(const Position &p, bool perpendicular=false) const
closest 2D-distance to point p (or -1 if perpendicular is true and the point is beyond this vector)
double nearest_offset_to_point2D(const Position &p, bool perpendicular=true) const
return the nearest offest to point 2D
void move2side(double amount, double maxExtension=100)
move position vector to side using certain ammount
PositionVector getSubpart2D(double beginOffset, double endOffset) const
get subpart of a position vector in two dimensions (Z is ignored)
double angleAt2D(int pos) const
get angle in certain position of position vector
PositionVector bezier(int numPoints)
return a bezier interpolation
int insertAtClosest(const Position &p, bool interpolateZ)
inserts p between the two closest positions
int removeClosest(const Position &p)
removes the point closest to p and return the removal index
PositionVector getSubpartByIndex(int beginIndex, int count) const
get subpart of a position vector using index and a cout
Position positionAtOffset2D(double pos, double lateralOffset=0) const
Returns the position at the given length.
const PositionVector & getShape() const
Returns whether the shape of the polygon.
Storage for geometrical objects.
const Polygons & getPolygons() const
Returns all polygons.
const std::string & getShapeType() const
Returns the (abstract) type of the Shape.
bool hasString(const std::string &str) const
T get(const std::string &str) const
void insert(const std::string str, const T key, bool checkDuplicates=true)
std::vector< std::string > getVector()
return vector of strings
static std::string escapeXML(const std::string &orig, const bool maskDoubleHyphen=false)
Replaces the standard escapes by their XML entities.
A structure which describes a connection between edges or lanes.
int fromLane
The lane the connections starts at.
int toLane
The lane the connections yields in.
NBEdge * toEdge
The edge the connections yields in.
double vmax
maximum velocity
std::string id
id of Connection
std::string type
the type of this lane