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