|
SUMO - Simulation of Urban MObility
|
00001 /****************************************************************************/ 00007 // Exporter writing networks using the openDRIVE format 00008 /****************************************************************************/ 00009 // SUMO, Simulation of Urban MObility; see http://sumo.sourceforge.net/ 00010 // Copyright (C) 2001-2011 DLR (http://www.dlr.de/) and contributors 00011 /****************************************************************************/ 00012 // 00013 // This program is free software; you can redistribute it and/or modify 00014 // it under the terms of the GNU General Public License as published by 00015 // the Free Software Foundation; either version 2 of the License, or 00016 // (at your option) any later version. 00017 // 00018 /****************************************************************************/ 00019 00020 00021 // =========================================================================== 00022 // included modules 00023 // =========================================================================== 00024 #ifdef _MSC_VER 00025 #include <windows_config.h> 00026 #else 00027 #include <config.h> 00028 #endif 00029 #include "NWWriter_OpenDrive.h" 00030 #include <utils/common/MsgHandler.h> 00031 #include <netbuild/NBEdge.h> 00032 #include <netbuild/NBEdgeCont.h> 00033 #include <netbuild/NBNode.h> 00034 #include <netbuild/NBNodeCont.h> 00035 #include <netbuild/NBNetBuilder.h> 00036 #include <utils/options/OptionsCont.h> 00037 #include <utils/iodevices/OutputDevice.h> 00038 #include <utils/common/StdDefs.h> 00039 00040 #ifdef CHECK_MEMORY_LEAKS 00041 #include <foreign/nvwa/debug_new.h> 00042 #endif // CHECK_MEMORY_LEAKS 00043 00044 00045 00046 // =========================================================================== 00047 // method definitions 00048 // =========================================================================== 00049 // --------------------------------------------------------------------------- 00050 // static methods 00051 // --------------------------------------------------------------------------- 00052 void 00053 NWWriter_OpenDrive::writeNetwork(const OptionsCont& oc, NBNetBuilder& nb) { 00054 // check whether a matsim-file shall be generated 00055 if (!oc.isSet("opendrive-output")) { 00056 return; 00057 } 00058 // some internal mapping containers 00059 int edgeID = 0; 00060 int nodeID = 0; 00061 StringBijection<int> edgeMap; 00062 StringBijection<int> nodeMap; 00063 // 00064 OutputDevice& device = OutputDevice::getDevice(oc.getString("opendrive-output")); 00065 device << "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n"; 00066 device << "<OpenDRIVE>\n"; 00067 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"; 00068 // write normal edges (road) 00069 const NBEdgeCont& ec = nb.getEdgeCont(); 00070 for (std::map<std::string, NBEdge*>::const_iterator i=ec.begin(); i!=ec.end(); ++i) { 00071 const NBEdge* e = (*i).second; 00072 device << " <road name=\"" << e->getStreetName() << "\" length=\"" << e->getLength() << "\" id=\"" << getID(e->getID(), edgeMap, edgeID) << "\" junction=\"-1\">\n"; 00073 device << " <link>\n"; 00074 device << " <predecessor elementType=\"junction\" elementId=\"" << getID(e->getFromNode()->getID(), nodeMap, nodeID) << "\"/>\n"; 00075 device << " <successor elementType=\"junction\" elementId=\"" << getID(e->getToNode()->getID(), nodeMap, nodeID) << "\"/>\n"; 00076 device << " </link>\n"; 00077 device << " <type s=\"0\" type=\"town\"/>\n"; 00078 writePlanView(e->getGeometry(), device); 00079 device << " <elevationProfile><elevation s=\"0\" a=\"0\" b=\"0\" c=\"0\" d=\"0\"/></elevationProfile>\n"; 00080 device << " <lateralProfile></lateralProfile>\n"; 00081 device << " <lanes>\n"; 00082 device << " <laneSection s=\"0\">\n"; 00083 writeEmptyCenterLane(device); 00084 device << " <right>\n"; 00085 const std::vector<NBEdge::Lane> &lanes = e->getLanes(); 00086 for (int j=e->getNumLanes(); --j>=0;) { 00087 device << " <lane id=\"-" << e->getNumLanes()-j <<"\" type=\"driving\" level=\"0\">\n"; 00088 device << " <link>\n"; 00089 device << " <predecessor id=\"-1\"/>\n"; // internal roads have this 00090 device << " <successor id=\"-1\"/>\n"; // internal roads have this 00091 device << " </link>\n"; 00092 device << " <width sOffset=\"0\" a=\"" << lanes[j].width << "\" b=\"0\" c=\"0\" d=\"0\"/>\n"; 00093 device << " <roadMark sOffset=\"0\" type=\"broken\" weight=\"standard\" color=\"standard\" width=\"0.13\"/>\n"; 00094 device << " </lane>\n"; 00095 } 00096 device << " </right>\n"; 00097 device << " </laneSection>\n"; 00098 device << " </lanes>\n"; 00099 device << " <objects></objects>\n"; 00100 device << " <signals></signals>\n"; 00101 device << " </road>\n"; 00102 } 00103 device << "\n"; 00104 // write junction-internal edges (road) 00105 const NBNodeCont& nc = nb.getNodeCont(); 00106 for (std::map<std::string, NBNode*>::const_iterator i=nc.begin(); i!=nc.end(); ++i) { 00107 NBNode* n = (*i).second; 00108 unsigned int index = 0; 00109 const std::vector<NBEdge*> &incoming = (*i).second->getIncomingEdges(); 00110 for (std::vector<NBEdge*>::const_iterator j=incoming.begin(); j!=incoming.end(); ++j) { 00111 const std::vector<NBEdge::Connection> &elv = (*j)->getConnections(); 00112 for (std::vector<NBEdge::Connection>::const_iterator k=elv.begin(); k!=elv.end(); ++k) { 00113 if ((*k).toEdge==0) { 00114 continue; 00115 } 00116 const NBEdge::Connection& c = *k; 00117 PositionVector shape = c.shape; 00118 if (c.haveVia) { 00119 shape.appendWithCrossingPoint(c.viaShape); 00120 } 00121 device << " <road name=\"" << c.id << "\" length=\"" << shape.length() << "\" id=\"" << getID(c.id, edgeMap, edgeID) << "\" junction=\"" << getID(n->getID(), nodeMap, nodeID) << "\">\n"; 00122 device << " <link>\n"; 00123 device << " <predecessor elementType=\"road\" elementId=\"" << getID((*j)->getID(), edgeMap, edgeID) << "\"/>\n"; 00124 device << " <successor elementType=\"road\" elementId=\"" << getID((*k).toEdge->getID(), edgeMap, edgeID) << "\"/>\n"; 00125 device << " </link>\n"; 00126 device << " <type s=\"0\" type=\"town\"/>\n"; 00127 writePlanView(shape, device); 00128 device << " <elevationProfile><elevation s=\"0\" a=\"0\" b=\"0\" c=\"0\" d=\"0\"/></elevationProfile>\n"; 00129 device << " <lateralProfile></lateralProfile>\n"; 00130 device << " <lanes>\n"; 00131 device << " <laneSection s=\"0\">\n"; 00132 writeEmptyCenterLane(device); 00133 device << " <right>\n"; 00134 device << " <lane id=\"-1\" type=\"driving\" level=\"0\">\n"; 00135 device << " <link>\n"; 00136 //device << " <predecessor id=\"1\"/>\n";// !!! 00137 //device << " <successor id=\"-1\"/>\n";// !!! 00138 device << " </link>\n"; 00139 device << " <width sOffset=\"0\" a=\"" << SUMO_const_laneWidth << "\" b=\"0\" c=\"0\" d=\"0\"/>\n"; 00140 device << " <roadMark sOffset=\"0\" type=\"broken\" weight=\"standard\" color=\"standard\" width=\"0.13\"/>\n"; 00141 device << " </lane>\n"; 00142 device << " </right>\n"; 00143 device << " </laneSection>\n"; 00144 device << " </lanes>\n"; 00145 device << " <objects></objects>\n"; 00146 device << " <signals></signals>\n"; 00147 device << " </road>\n"; 00148 } 00149 } 00150 } 00151 00152 // write junctions (junction) 00153 for (std::map<std::string, NBNode*>::const_iterator i=nc.begin(); i!=nc.end(); ++i) { 00154 NBNode* n = (*i).second; 00155 device << " <junction name=\"" << n->getID() << "\" id=\"" << getID(n->getID(), nodeMap, nodeID) << "\">\n"; 00156 unsigned int index = 0; 00157 const std::vector<NBEdge*> &incoming = n->getIncomingEdges(); 00158 for (std::vector<NBEdge*>::const_iterator j=incoming.begin(); j!=incoming.end(); ++j) { 00159 const std::vector<NBEdge::Connection> &elv = (*j)->getConnections(); 00160 for (std::vector<NBEdge::Connection>::const_iterator k=elv.begin(); k!=elv.end(); ++k) { 00161 if ((*k).toEdge==0) { 00162 continue; 00163 } 00164 device << " <connection id=\"" << index << "\" incomingRoad=\"" << getID((*j)->getID(), edgeMap, edgeID) 00165 << "\" connectingRoad=\"" << getID((*k).id, edgeMap, edgeID) << "\" contactPoint=\"start\"/>\n"; 00166 ++index; 00167 } 00168 } 00169 device << " </junction>\n"; 00170 } 00171 00172 device << "</OpenDRIVE>\n"; 00173 device.close(); 00174 } 00175 00176 00177 void 00178 NWWriter_OpenDrive::writePlanView(const PositionVector& shape, OutputDevice& device) { 00179 device << " <planView>\n"; 00180 SUMOReal offset = 0; 00181 for (unsigned int j=0; j<shape.size()-1; ++j) { 00182 const Position& p = shape[j]; 00183 Line l = shape.lineAt(j); 00184 device << " <geometry s=\"" << offset << "\" x=\"" << p.x() << "\" y=\"" << p.y() << "\" hdg=\"" << l.atan2Angle() << "\" length=\"" << l.length() << "\"><line/></geometry>\n"; 00185 offset += l.length(); 00186 } 00187 device << " </planView>\n"; 00188 } 00189 00190 00191 void 00192 NWWriter_OpenDrive::writeEmptyCenterLane(OutputDevice& device) { 00193 device << " <center>\n"; 00194 device << " <lane id=\"0\" type=\"driving\" level= \"0\">\n"; 00195 device << " <link></link>\n"; 00196 device << " <roadMark sOffset=\"0\" type=\"solid\" weight=\"standard\" color=\"standard\" width=\"0.13\"/>\n"; 00197 device << " </lane>\n"; 00198 device << " </center>\n"; 00199 } 00200 00201 00202 int 00203 NWWriter_OpenDrive::getID(const std::string& origID, StringBijection<int> &map, int& lastID) { 00204 if (map.hasString(origID)) { 00205 return map.get(origID); 00206 } 00207 map.insert(origID, lastID++); 00208 return lastID - 1; 00209 } 00210 00211 00212 /****************************************************************************/ 00213