49 #ifdef CHECK_MEMORY_LEAKS 51 #endif // CHECK_MEMORY_LEAKS 54 #define DEBUGCOND true 56 #define MIN_TURN_DIAMETER 2.0 68 if (!oc.
isSet(
"opendrive-output")) {
71 const bool origNames = oc.
getBool(
"output.original-names");
79 device <<
"<?xml version=\"1.0\" encoding=\"utf-8\"?>\n";
82 std::string dstr(ctime(&now));
87 device.openTag(
"header");
88 device.writeAttr(
"revMajor",
"1");
89 device.writeAttr(
"revMinor",
"4");
90 device.writeAttr(
"name",
"");
91 device.writeAttr(
"version",
"1.00");
92 device.writeAttr(
"date", dstr.substr(0, dstr.length() - 1));
93 device.writeAttr(
"north", b.
ymax());
94 device.writeAttr(
"south", b.
ymin());
95 device.writeAttr(
"east", b.
xmax());
96 device.writeAttr(
"west", b.
xmin());
97 device.writeAttr(
"maxRoad", ec.
size());
98 device.writeAttr(
"maxJunc", nc.
size());
99 device.writeAttr(
"maxPrg", 0);
103 for (std::map<std::string, NBEdge*>::const_iterator i = ec.
begin(); i != ec.
end(); ++i) {
104 const NBEdge* e = (*i).second;
106 device <<
" <link>\n";
107 device <<
" <predecessor elementType=\"junction\" elementId=\"" <<
getID(e->
getFromNode()->
getID(), nodeMap, nodeID) <<
"\"/>\n";
108 device <<
" <successor elementType=\"junction\" elementId=\"" <<
getID(e->
getToNode()->
getID(), nodeMap, nodeID) <<
"\"/>\n";
109 device <<
" </link>\n";
110 device <<
" <type s=\"0\" type=\"town\"/>\n";
111 device <<
" <planView>\n";
112 device << std::setprecision(8);
114 const std::vector<NBEdge::Lane>& lanes = e->
getLanes();
116 #ifdef DEBUG_SMOOTH_GEOM 118 std::cout <<
"write planview for edge " << e->
getID() <<
"\n";
130 device <<
" </planView>\n";
132 device <<
" <lateralProfile/>\n";
133 device <<
" <lanes>\n";
134 device <<
" <laneSection s=\"0\">\n";
136 device <<
" <right>\n";
139 device <<
" <link/>\n";
147 device <<
" <width sOffset=\"0\" a=\"" << e->
getLaneWidth(j) <<
"\" b=\"0\" c=\"0\" d=\"0\"/>\n";
148 std::string markType =
"broken";
152 device <<
" <roadMark sOffset=\"0\" type=\"" << markType <<
"\" weight=\"standard\" color=\"standard\" width=\"0.13\"/>\n";
153 device <<
" <speed sOffset=\"0\" max=\"" << lanes[j].speed <<
"\"/>\n";
154 device <<
" </lane>\n";
156 device <<
" </right>\n";
157 device <<
" </laneSection>\n";
158 device <<
" </lanes>\n";
159 device <<
" <objects/>\n";
160 device <<
" <signals/>\n";
162 device <<
" <userData sumoId=\"" << e->
getID() <<
"\"/>\n";
164 device <<
" </road>\n";
168 for (std::map<std::string, NBNode*>::const_iterator i = nc.
begin(); i != nc.
end(); ++i) {
171 for (std::vector<NBEdge*>::const_iterator j = incoming.begin(); j != incoming.end(); ++j) {
172 const NBEdge* inEdge = *j;
173 const std::vector<NBEdge::Connection>& elv = inEdge->
getConnections();
174 for (std::vector<NBEdge::Connection>::const_iterator k = elv.begin(); k != elv.end(); ++k) {
187 if (init.size() == 0) {
188 fallBackShape.push_back(begShape.back());
189 fallBackShape.push_back(endShape.front());
192 length =
bezier(init, 12).length2D();
196 device <<
" <link>\n";
197 device <<
" <predecessor elementType=\"road\" elementId=\"" <<
getID(inEdge->
getID(), edgeMap, edgeID) <<
"\" contactPoint=\"end\"/>\n";
198 device <<
" <successor elementType=\"road\" elementId=\"" <<
getID(outEdge->
getID(), edgeMap, edgeID) <<
"\" contactPoint=\"start\"/>\n";
199 device <<
" </link>\n";
200 device <<
" <type s=\"0\" type=\"town\"/>\n";
201 device <<
" <planView>\n";
202 device << std::setprecision(8);
204 if (init.size() == 0) {
210 device <<
" </planView>\n";
212 device <<
" <lateralProfile/>\n";
213 device <<
" <lanes>\n";
214 device <<
" <laneSection s=\"0\">\n";
216 device <<
" <right>\n";
218 device <<
" <link>\n";
221 device <<
" </link>\n";
222 device <<
" <width sOffset=\"0\" a=\"" << width <<
"\" b=\"0\" c=\"0\" d=\"0\"/>\n";
223 device <<
" <roadMark sOffset=\"0\" type=\"none\" weight=\"standard\" color=\"standard\" width=\"0.13\"/>\n";
224 device <<
" </lane>\n";
225 device <<
" </right>\n";
226 device <<
" </laneSection>\n";
227 device <<
" </lanes>\n";
228 device <<
" <objects/>\n";
229 device <<
" <signals/>\n";
230 device <<
" </road>\n";
236 for (std::map<std::string, NBNode*>::const_iterator i = nc.
begin(); i != nc.
end(); ++i) {
238 device <<
" <junction name=\"" << n->
getID() <<
"\" id=\"" <<
getID(n->
getID(), nodeMap, nodeID) <<
"\">\n";
241 for (std::vector<NBEdge*>::const_iterator j = incoming.begin(); j != incoming.end(); ++j) {
242 const NBEdge* inEdge = *j;
243 const std::vector<NBEdge::Connection>& elv = inEdge->
getConnections();
244 for (std::vector<NBEdge::Connection>::const_iterator k = elv.begin(); k != elv.end(); ++k) {
250 device <<
" <connection id=\"" 251 << index <<
"\" incomingRoad=\"" <<
getID(inEdge->
getID(), edgeMap, edgeID)
252 <<
"\" connectingRoad=\"" 254 <<
"\" contactPoint=\"start\">\n";
258 device <<
" </connection>\n";
262 device <<
" </junction>\n";
272 for (
int j = 0; j < (int)shape.size() - 1; ++j) {
277 device <<
" <geometry s=\"" << offset <<
"\" x=\"" << p.
x() <<
"\" y=\"" << p.
y() <<
"\" hdg=\"" << hdg <<
"\" length=\"" << length <<
"\"><line/></geometry>\n";
278 elevationDevice <<
" <elevation s=\"" << offset <<
"\" a=\"" << p.
z() <<
"\" b=\"" << (p2.
z() - p.
z()) / length <<
"\" c=\"0\" d=\"0\"/>\n";
287 device <<
" <center>\n";
288 device <<
" <lane id=\"0\" type=\"none\" level= \"0\">\n";
289 device <<
" <link/>\n";
290 device <<
" <roadMark sOffset=\"0\" type=\"" << mark <<
"\" weight=\"standard\" color=\"standard\" width=\"" << markWidth <<
"\"/>\n";
291 device <<
" <width sOffset=\"0\" a=\"0\" b=\"0\" c=\"0\" d=\"0\"/>\n";
292 device <<
" </lane>\n";
293 device <<
" </center>\n";
300 return map.
get(origID);
302 map.
insert(origID, lastID++);
309 switch (permissions) {
328 if (permissions ==
SVCAll) {
344 if (laneIndex == -1) {
352 for (
int i = leftmost; i > laneIndex; i--) {
371 assert(init.size() == 3 || init.size() == 4);
376 init.
add(-p.x(), -p.y(), -p.z());
385 if (init.size() == 3) {
388 bU = 2 * init[1].x() - 2 * init[0].x();
389 cU = init[0].x() - 2 * init[1].x() + init[2].x();
393 bV = 2 * init[1].y() - 2 * init[0].y();
394 cV = init[0].y() - 2 * init[1].y() + init[2].y();
399 bZ = (2 * init[1].z() - 2 * init[0].z()) / length;
400 cZ = (init[0].z() - 2 * init[1].z() + init[2].z()) / (length * length);
406 bU = 3 * init[1].x() - 3 * init[0].x();
407 cU = 3 * init[0].x() - 6 * init[1].x() + 3 * init[2].x();
408 dU = -init[0].x() + 3 * init[1].x() - 3 * init[2].x() + init[3].x();
411 bV = 3 * init[1].y() - 3 * init[0].y();
412 cV = 3 * init[0].y() - 6 * init[1].y() + 3 * init[2].y();
413 dV = -init[0].y() + 3 * init[1].y() - 3 * init[2].y() + init[3].y();
417 bZ = (3 * init[1].z() - 3 * init[0].z()) / length;
418 cZ = (3 * init[0].z() - 6 * init[1].z() + 3 * init[2].z()) / (length * length);
419 dZ = (-init[0].z() + 3 * init[1].z() - 3 * init[2].z() + init[3].z()) / (length * length * length);
442 elevationDevice.
openTag(
"elevation");
450 return offset + length;
456 #ifdef DEBUG_SMOOTH_GEOM 458 std::cout <<
"writeGeomSmooth\n n=" << shape.size() <<
" shape=" <<
toString(shape) <<
"\n";
463 const SUMOReal curveCutout = longThresh / 2;
465 assert(longThresh >= 2 * curveCutout);
466 assert(shape.size() > 2);
472 for (
int j = 1; j < (int)shape.size() - 1; ++j) {
480 maxAngleDiff =
MAX2(maxAngleDiff, dAngle);
481 #ifdef DEBUG_SMOOTH_GEOM 483 std::cout <<
" j=" << j <<
" dAngle=" <<
RAD2DEG(dAngle) <<
" length1=" << length1 <<
" length2=" << length2 <<
"\n";
486 if (dAngle > angleThresh
487 && (length1 > longThresh || j == 1)
488 && (length2 > longThresh || j == (
int)shape.size() - 2)) {
491 shape2.removeClosest(p1);
495 const int numPoints = (int)shape2.size();
496 #ifdef DEBUG_SMOOTH_GEOM 498 std::cout <<
" n=" << numPoints <<
" shape2=" <<
toString(shape2) <<
"\n";
502 if (maxAngleDiff < angleThresh) {
504 #ifdef DEBUG_SMOOTH_GEOM 506 std::cout <<
" special case: all lines. maxAngleDiff=" << maxAngleDiff <<
"\n";
514 for (
int j = 0; j < numPoints - 1; ++j) {
521 if (lineLength >= longThresh) {
523 #ifdef DEBUG_SMOOTH_GEOM 525 std::cout <<
" writeLine=" <<
toString(line) <<
"\n";
535 begShape.
add(p0 - begShape.back());
536 }
else if (j == 1 || p0.
distanceTo2D(shape2[j - 1]) > longThresh) {
538 begShape.push_back(shape2[j - 1]);
539 begShape.push_back(p0);
542 begShape.push_back(shape2[j - 1]);
543 begShape.push_back(p1);
544 begShape.
add(p0 - begShape.back());
546 if (j == numPoints - 2) {
549 endShape.
add(p1 - endShape.front());
550 }
else if (j == numPoints - 3 || p1.
distanceTo2D(shape2[j + 2]) > longThresh) {
552 endShape.push_back(p1);
553 endShape.push_back(shape2[j + 2]);
556 endShape.push_back(p0);
557 endShape.push_back(shape2[j + 2]);
558 endShape.
add(p1 - endShape.front());
562 if (init.size() == 0) {
565 #ifdef DEBUG_SMOOTH_GEOM 567 std::cout <<
" writeLine lineLength=" << lineLength <<
" begShape=" <<
toString(begShape) <<
" endShape=" <<
toString(endShape) <<
" init=" <<
toString(init) <<
"\n";
573 offset =
writeGeomPP3(device, elevationDevice, init, curveLength, offset);
574 #ifdef DEBUG_SMOOTH_GEOM 576 std::cout <<
" writeCurve lineLength=" << lineLength <<
" curveLength=" << curveLength <<
" begShape=" <<
toString(begShape) <<
" endShape=" <<
toString(endShape) <<
" init=" <<
toString(init) <<
"\n";
589 SUMOReal z = shape.size() == 0 ? 0 : shape[0].z();
590 for (
int i = 1; i < (int)shape.size(); ++i) {
596 device <<
" <elevationProfile>\n";
598 device <<
" <elevation s=\"0\" a=\"" << z <<
"\" b=\"0\" c=\"0\" d=\"0\"/>\n";
602 device <<
" </elevationProfile>\n";
static SUMOReal writeGeomLines(const PositionVector &shape, OutputDevice &device, OutputDevice &elevationDevice, SUMOReal offset=0)
write geometry as sequence of lines (sumo style)
static SUMOReal writeGeomPP3(OutputDevice &device, OutputDevice &elevationDevice, PositionVector init, SUMOReal length, SUMOReal offset=0)
write geometry as a single bezier curve (paramPoly3)
OutputDevice & writeAttr(const SumoXMLAttr attr, const T &val)
writes a named attribute
const EdgeVector & getIncomingEdges() const
Returns this node's incoming edges.
A structure which describes a connection between edges or lanes.
int toLane
The lane the connections yields in.
std::string getString() const
Returns the current content as a string.
NBEdge * toEdge
The edge the connections yields in.
int size() const
Returns the number of edges.
bool hasString(const std::string &str) const
vehicle is a not electrified rail
SUMOReal ymin() const
Returns minimum y-coordinate.
const std::vector< NBEdge::Lane > & getLanes() const
Returns the lane definitions.
bool getBool(const std::string &name) const
Returns the boolean-value of the named option (only for Option_Bool)
The representation of a single edge during network building.
static std::string escapeXML(const std::string &orig)
Replaces the standard escapes by their XML entities.
SUMOReal xmin() const
Returns minimum x-coordinate.
static void writeGeomSmooth(const PositionVector &shape, SUMOReal speed, OutputDevice &device, OutputDevice &elevationDevice)
write geometry as sequence of lines and bezier curves
void setPrecision(int precision=OUTPUT_ACCURACY)
Sets the precison or resets it to default.
SUMOReal getLaneWidth() const
Returns the default width of lanes of this edge.
bool isRailway(SVCPermissions permissions)
Returns whether an edge with the given permission is a railway edge.
const SVCPermissions SVCAll
static SUMOReal angleDiff(const SUMOReal angle1, const SUMOReal angle2)
Returns the difference of the second angle to the first angle in radiants.
SUMOReal x() const
Returns the x-position.
Position positionAtOffset2D(SUMOReal pos, SUMOReal lateralOffset=0) const
Returns the position at the given length.
SUMOReal xmax() const
Returns maximum x-coordinate.
A class that stores a 2D geometrical boundary.
vehicle is a (possibly fast moving) electric rail
void rotate2D(SUMOReal angle)
std::string getString(const std::string &name) const
Returns the string-value of the named option (only for Option_String)
const std::string & getID() const
Returns the id.
SUMOReal length2D() const
Returns the length.
void insert(const std::string str, const T key, bool checkDuplicates=true)
static void writeNetwork(const OptionsCont &oc, NBNetBuilder &nb)
Writes the network into a openDRIVE-file.
std::map< std::string, NBEdge * >::const_iterator end() const
Returns the pointer to the end of the stored edges.
std::string getInternalLaneID() const
int fromLane
The lane the connections starts at.
A point in 2D or 3D with translation and scaling methods.
NBEdgeCont & getEdgeCont()
Returns the edge container.
void add(SUMOReal xoff, SUMOReal yoff, SUMOReal zoff)
SUMOReal z() const
Returns the z-position.
int getNumLanes() const
Returns the number of lanes.
bool isTurningDirectionAt(const NBEdge *const edge) const
Returns whether the given edge is the opposite direction to this edge.
static void writeEmptyCenterLane(OutputDevice &device, const std::string &mark, SUMOReal markWidth)
Storage for edges, including some functionality operating on multiple edges.
void bezier(int npts, SUMOReal b[], int cpts, SUMOReal p[])
std::map< std::string, NBNode * >::const_iterator end() const
Returns the pointer to the end of the stored nodes.
const Boundary & getConvBoundary() const
Returns the converted boundary.
std::string toString(const T &t, std::streamsize accuracy=OUTPUT_ACCURACY)
vehicle is a passenger car (a "normal" car)
std::map< std::string, NBEdge * >::const_iterator begin() const
Returns the pointer to the begin of the stored edges.
SVCPermissions getPermissions(int lane=-1) const
get the union of allowed classes over all lanes or for a specific lane
static std::string getLaneType(SVCPermissions permissions)
NBNode * getToNode() const
Returns the destination node of the edge.
SUMOReal angleAt2D(int pos) const
get angle in certain position of position vector
NBNodeCont & getNodeCont()
Returns the node container.
Instance responsible for building networks.
static OutputDevice & getDevice(const std::string &name)
Returns the described OutputDevice.
SUMOReal y() const
Returns the y-position.
A storage for options typed value containers)
static PositionVector getLeftLaneBorder(const NBEdge *edge, int laneIndex=-1)
get the left border of the given lane (the leftmost one by default)
static const GeoConvHelper & getFinal()
the coordinate transformation for writing the location element and for tracking the original coordina...
Represents a single node (junction) during network building.
T get(const std::string &str) const
SUMOReal distanceTo2D(const Position &p2) const
returns the euclidean distance in the x-y-plane
void move2side(SUMOReal amount)
move position vector to side using certain ammount
Static storage of an output device and its base (abstract) implementation.
bool closeTag()
Closes the most recently opened tag.
SUMOReal ymax() const
Returns maximum y-coordinate.
int size() const
Returns the number of known nodes.
static PositionVector bezierControlPoints(const PositionVector &begShape, const PositionVector &endShape, bool isTurnaround, SUMOReal extrapolateBeg, SUMOReal extrapolateEnd)
SUMOReal getSpeed() const
Returns the speed allowed on this edge.
Container for nodes during the netbuilding process.
static int getID(const std::string &origID, StringBijection< int > &map, int &lastID)
const std::string & getStreetName() const
Returns the street name of this edge.
const std::vector< Connection > & getConnections() const
Returns the connections.
std::map< std::string, NBNode * >::const_iterator begin() const
Returns the pointer to the begin of the stored nodes.
const PositionVector & getLaneShape(int i) const
Returns the shape of the nth lane.
static void writeElevationProfile(const PositionVector &shape, OutputDevice &device, const OutputDevice_String &elevationDevice)
OutputDevice & openTag(const std::string &xmlElement)
Opens an XML tag.
SUMOReal angleTo2D(const Position &other) const
returns the angle in the plane of the vector pointing from here to the other position ...
An output device that encapsulates an ofstream.
SUMOReal getLength() const
Returns the computed length of the edge.
bool isSet(const std::string &name, bool failOnNonExistant=true) const
Returns the information whether the named option is set.
NBNode * getFromNode() const
Returns the origin node of the edge.