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-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 
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Friends Defines