SUMO - Simulation of Urban MObility
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
NWWriter_OpenDrive.cpp
Go to the documentation of this file.
1 /****************************************************************************/
7 // Exporter writing networks using the openDRIVE format
8 /****************************************************************************/
9 // SUMO, Simulation of Urban MObility; see http://sumo.sourceforge.net/
10 // Copyright (C) 2001-2012 DLR (http://www.dlr.de/) and contributors
11 /****************************************************************************/
12 //
13 // This file is part of SUMO.
14 // SUMO is free software: you can redistribute it and/or modify
15 // it under the terms of the GNU General Public License as published by
16 // the Free Software Foundation, either version 3 of the License, or
17 // (at your option) any later version.
18 //
19 /****************************************************************************/
20 
21 
22 // ===========================================================================
23 // included modules
24 // ===========================================================================
25 #ifdef _MSC_VER
26 #include <windows_config.h>
27 #else
28 #include <config.h>
29 #endif
30 #include "NWWriter_OpenDrive.h"
32 #include <netbuild/NBEdge.h>
33 #include <netbuild/NBEdgeCont.h>
34 #include <netbuild/NBNode.h>
35 #include <netbuild/NBNodeCont.h>
36 #include <netbuild/NBNetBuilder.h>
39 #include <utils/common/StdDefs.h>
40 
41 #ifdef CHECK_MEMORY_LEAKS
42 #include <foreign/nvwa/debug_new.h>
43 #endif // CHECK_MEMORY_LEAKS
44 
45 
46 
47 // ===========================================================================
48 // method definitions
49 // ===========================================================================
50 // ---------------------------------------------------------------------------
51 // static methods
52 // ---------------------------------------------------------------------------
53 void
55  // check whether a matsim-file shall be generated
56  if (!oc.isSet("opendrive-output")) {
57  return;
58  }
59  // some internal mapping containers
60  int edgeID = 0;
61  int nodeID = 0;
62  StringBijection<int> edgeMap;
63  StringBijection<int> nodeMap;
64  //
65  OutputDevice& device = OutputDevice::getDevice(oc.getString("opendrive-output"));
66  device << "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n";
67  device << "<OpenDRIVE>\n";
68  device << " <header revMajor=\"1\" revMinor=\"3\" name=\"\" version=\"1.00\" date=\"!!!\" north=\"0.0000000000000000e+00\" south=\"0.0000000000000000e+00\" east=\"0.0000000000000000e+00\" west=\"0.0000000000000000e+00\" maxRoad=\"517\" maxJunc=\"2\" maxPrg=\"0\"/>\n";
69  // write normal edges (road)
70  const NBEdgeCont& ec = nb.getEdgeCont();
71  for (std::map<std::string, NBEdge*>::const_iterator i = ec.begin(); i != ec.end(); ++i) {
72  const NBEdge* e = (*i).second;
73  device << " <road name=\"" << e->getStreetName() << "\" length=\"" << e->getLength() << "\" id=\"" << getID(e->getID(), edgeMap, edgeID) << "\" junction=\"-1\">\n";
74  device << " <link>\n";
75  device << " <predecessor elementType=\"junction\" elementId=\"" << getID(e->getFromNode()->getID(), nodeMap, nodeID) << "\"/>\n";
76  device << " <successor elementType=\"junction\" elementId=\"" << getID(e->getToNode()->getID(), nodeMap, nodeID) << "\"/>\n";
77  device << " </link>\n";
78  device << " <type s=\"0\" type=\"town\"/>\n";
79  writePlanView(e->getGeometry(), device);
80  device << " <elevationProfile><elevation s=\"0\" a=\"0\" b=\"0\" c=\"0\" d=\"0\"/></elevationProfile>\n";
81  device << " <lateralProfile></lateralProfile>\n";
82  device << " <lanes>\n";
83  device << " <laneSection s=\"0\">\n";
84  writeEmptyCenterLane(device);
85  device << " <right>\n";
86  const std::vector<NBEdge::Lane> &lanes = e->getLanes();
87  for (int j = e->getNumLanes(); --j >= 0;) {
88  device << " <lane id=\"-" << e->getNumLanes() - j << "\" type=\"driving\" level=\"0\">\n";
89  device << " <link>\n";
90  device << " <predecessor id=\"-1\"/>\n"; // internal roads have this
91  device << " <successor id=\"-1\"/>\n"; // internal roads have this
92  device << " </link>\n";
93  SUMOReal width = lanes[j].width<0||!e->hasLaneSpecificWidth() ? SUMO_const_laneWidth : lanes[j].width;
94  device << " <width sOffset=\"0\" a=\"" << width << "\" b=\"0\" c=\"0\" d=\"0\"/>\n";
95  std::string markType = "broken";
96  if(j==0) {
97  markType = "solid";
98  }
99  device << " <roadMark sOffset=\"0\" type=\"" << markType << "\" weight=\"standard\" color=\"standard\" width=\"0.13\"/>\n";
100  device << " </lane>\n";
101  }
102  device << " </right>\n";
103  device << " </laneSection>\n";
104  device << " </lanes>\n";
105  device << " <objects></objects>\n";
106  device << " <signals></signals>\n";
107  device << " </road>\n";
108  }
109  device << "\n";
110  // write junction-internal edges (road)
111  const NBNodeCont& nc = nb.getNodeCont();
112  for (std::map<std::string, NBNode*>::const_iterator i = nc.begin(); i != nc.end(); ++i) {
113  NBNode* n = (*i).second;
114  const std::vector<NBEdge*> &incoming = (*i).second->getIncomingEdges();
115  for (std::vector<NBEdge*>::const_iterator j = incoming.begin(); j != incoming.end(); ++j) {
116  const std::vector<NBEdge::Connection> &elv = (*j)->getConnections();
117  for (std::vector<NBEdge::Connection>::const_iterator k = elv.begin(); k != elv.end(); ++k) {
118  if ((*k).toEdge == 0) {
119  continue;
120  }
121  const NBEdge::Connection& c = *k;
122  PositionVector shape = c.shape;
123  if (c.haveVia) {
125  }
126  device << " <road name=\"" << c.id << "\" length=\"" << shape.length() << "\" id=\"" << getID(c.id, edgeMap, edgeID) << "\" junction=\"" << getID(n->getID(), nodeMap, nodeID) << "\">\n";
127  device << " <link>\n";
128  device << " <predecessor elementType=\"road\" elementId=\"" << getID((*j)->getID(), edgeMap, edgeID) << "\"/>\n";
129  device << " <successor elementType=\"road\" elementId=\"" << getID((*k).toEdge->getID(), edgeMap, edgeID) << "\"/>\n";
130  device << " </link>\n";
131  device << " <type s=\"0\" type=\"town\"/>\n";
132  writePlanView(shape, device);
133  device << " <elevationProfile><elevation s=\"0\" a=\"0\" b=\"0\" c=\"0\" d=\"0\"/></elevationProfile>\n";
134  device << " <lateralProfile></lateralProfile>\n";
135  device << " <lanes>\n";
136  device << " <laneSection s=\"0\">\n";
137  writeEmptyCenterLane(device);
138  device << " <right>\n";
139  device << " <lane id=\"-1\" type=\"driving\" level=\"0\">\n";
140  device << " <link>\n";
141  //device << " <predecessor id=\"1\"/>\n";// !!!
142  //device << " <successor id=\"-1\"/>\n";// !!!
143  device << " </link>\n";
144  device << " <width sOffset=\"0\" a=\"" << SUMO_const_laneWidth << "\" b=\"0\" c=\"0\" d=\"0\"/>\n";
145  device << " <roadMark sOffset=\"0\" type=\"broken\" weight=\"standard\" color=\"standard\" width=\"0.13\"/>\n";
146  device << " </lane>\n";
147  device << " </right>\n";
148  device << " </laneSection>\n";
149  device << " </lanes>\n";
150  device << " <objects></objects>\n";
151  device << " <signals></signals>\n";
152  device << " </road>\n";
153  }
154  }
155  }
156 
157  // write junctions (junction)
158  for (std::map<std::string, NBNode*>::const_iterator i = nc.begin(); i != nc.end(); ++i) {
159  NBNode* n = (*i).second;
160  device << " <junction name=\"" << n->getID() << "\" id=\"" << getID(n->getID(), nodeMap, nodeID) << "\">\n";
161  unsigned int index = 0;
162  const std::vector<NBEdge*> &incoming = n->getIncomingEdges();
163  for (std::vector<NBEdge*>::const_iterator j = incoming.begin(); j != incoming.end(); ++j) {
164  const std::vector<NBEdge::Connection> &elv = (*j)->getConnections();
165  for (std::vector<NBEdge::Connection>::const_iterator k = elv.begin(); k != elv.end(); ++k) {
166  if ((*k).toEdge == 0) {
167  continue;
168  }
169  device << " <connection id=\"" << index << "\" incomingRoad=\"" << getID((*j)->getID(), edgeMap, edgeID)
170  << "\" connectingRoad=\"" << getID((*k).id, edgeMap, edgeID) << "\" contactPoint=\"start\"/>\n";
171  ++index;
172  }
173  }
174  device << " </junction>\n";
175  }
176 
177  device << "</OpenDRIVE>\n";
178  device.close();
179 }
180 
181 
182 void
184  device << " <planView>\n";
185  SUMOReal offset = 0;
186  for (unsigned int j = 0; j < shape.size() - 1; ++j) {
187  const Position& p = shape[j];
188  Line l = shape.lineAt(j);
189  SUMOReal hdg = atan2(l.p2().y() - l.p1().y(), l.p2().x() - l.p1().x());
190  device << " <geometry s=\"" << offset << "\" x=\"" << p.x() << "\" y=\"" << p.y() << "\" hdg=\"" << hdg << "\" length=\"" << l.length() << "\"><line/></geometry>\n";
191  offset += l.length();
192  }
193  device << " </planView>\n";
194 }
195 
196 
197 void
199  device << " <center>\n";
200  device << " <lane id=\"0\" type=\"none\" level= \"0\">\n";
201  device << " <link></link>\n";
202  device << " <roadMark sOffset=\"0\" type=\"solid\" weight=\"standard\" color=\"standard\" width=\"0.13\"/>\n";
203  device << " <width sOffset=\"0\" a=\"0\" b=\"0\" c=\"0\" d=\"0\"/>\n";
204  device << " </lane>\n";
205  device << " </center>\n";
206 }
207 
208 
209 int
210 NWWriter_OpenDrive::getID(const std::string& origID, StringBijection<int> &map, int& lastID) {
211  if (map.hasString(origID)) {
212  return map.get(origID);
213  }
214  map.insert(origID, lastID++);
215  return lastID - 1;
216 }
217 
218 
219 /****************************************************************************/
220