SUMO - Simulation of Urban MObility

NWWriter_OpenDrive.cpp

Go to the documentation of this file.
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 
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Friends Defines