SUMO - Simulation of Urban MObility

NWWriter_XML.cpp

Go to the documentation of this file.
00001 /****************************************************************************/
00009 // Exporter writing networks using XML (native input) format
00010 /****************************************************************************/
00011 // SUMO, Simulation of Urban MObility; see http://sumo.sourceforge.net/
00012 // Copyright (C) 2001-2012 DLR (http://www.dlr.de/) and contributors
00013 /****************************************************************************/
00014 //
00015 //   This file is part of SUMO.
00016 //   SUMO is free software: you can redistribute it and/or modify
00017 //   it under the terms of the GNU General Public License as published by
00018 //   the Free Software Foundation, either version 3 of the License, or
00019 //   (at your option) any later version.
00020 //
00021 /****************************************************************************/
00022 
00023 
00024 // ===========================================================================
00025 // included modules
00026 // ===========================================================================
00027 #ifdef _MSC_VER
00028 #include <windows_config.h>
00029 #else
00030 #include <config.h>
00031 #endif
00032 #include <algorithm>
00033 #include <utils/common/MsgHandler.h>
00034 #include <netbuild/NBEdge.h>
00035 #include <netbuild/NBEdgeCont.h>
00036 #include <netbuild/NBNode.h>
00037 #include <netbuild/NBNodeCont.h>
00038 #include <netbuild/NBNetBuilder.h>
00039 #include <utils/common/ToString.h>
00040 #include <utils/options/OptionsCont.h>
00041 #include <utils/iodevices/OutputDevice.h>
00042 #include <utils/geom/GeoConvHelper.h>
00043 #include "NWFrame.h"
00044 #include "NWWriter_SUMO.h"
00045 #include "NWWriter_XML.h"
00046 
00047 #ifdef CHECK_MEMORY_LEAKS
00048 #include <foreign/nvwa/debug_new.h>
00049 #endif // CHECK_MEMORY_LEAKS
00050 
00051 
00052 
00053 // ===========================================================================
00054 // method definitions
00055 // ===========================================================================
00056 // ---------------------------------------------------------------------------
00057 // static methods
00058 // ---------------------------------------------------------------------------
00059 void
00060 NWWriter_XML::writeNetwork(const OptionsCont& oc, NBNetBuilder& nb) {
00061     // check whether a matsim-file shall be generated
00062     if (!oc.isSet("plain-output-prefix")) {
00063         return;
00064     }
00065     writeNodes(oc, nb.getNodeCont());
00066     writeEdgesAndConnections(oc, nb.getNodeCont(), nb.getEdgeCont());
00067     writeTrafficLights(oc, nb.getTLLogicCont(), nb.getEdgeCont());
00068 }
00069 
00070 
00071 void
00072 NWWriter_XML::writeNodes(const OptionsCont& oc, NBNodeCont& nc) {
00073     const GeoConvHelper& gch = GeoConvHelper::getFinal();
00074     bool useGeo = oc.exists("proj.plain-geo") && oc.getBool("proj.plain-geo");
00075     if (useGeo && !gch.usingGeoProjection()) {
00076         WRITE_WARNING("Ignoring option \"proj.plain-geo\" because no geo-conversion has been defined");
00077         useGeo = false;
00078     }
00079     const bool geoAccuracy = useGeo || gch.usingInverseGeoProjection();
00080 
00081     OutputDevice& device = OutputDevice::getDevice(oc.getString("plain-output-prefix") + ".nod.xml");
00082     device.writeXMLHeader("nodes", SUMOSAXAttributes::ENCODING, NWFrame::MAJOR_VERSION + " xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:noNamespaceSchemaLocation=\"http://sumo.sf.net/xsd/nodes_file.xsd\"");
00083 
00084     // write network offsets and projection to allow reconstruction of original coordinates
00085     if (!useGeo) {
00086         NWWriter_SUMO::writeLocation(device);
00087     }
00088 
00089     // write nodes
00090     for (std::map<std::string, NBNode*>::const_iterator i = nc.begin(); i != nc.end(); ++i) {
00091         NBNode* n = (*i).second;
00092         device.openTag(SUMO_TAG_NODE);
00093         device.writeAttr(SUMO_ATTR_ID, n->getID());
00094         // write position
00095         Position pos = n->getPosition();
00096         if (useGeo) {
00097             gch.cartesian2geo(pos);
00098         }
00099         if (geoAccuracy) {
00100             device.setPrecision(GEO_OUTPUT_ACCURACY);
00101         }
00102         NWFrame::writePositionLong(pos, device);
00103         if (geoAccuracy) {
00104             device.setPrecision();
00105         }
00106 
00107         device.writeAttr(SUMO_ATTR_TYPE, toString(n->getType()));
00108         if (n->isTLControlled()) {
00109             const std::set<NBTrafficLightDefinition*> &tlss = n->getControllingTLS();
00110             // set may contain multiple programs for the same id.
00111             // make sure ids are unique and sorted
00112             std::set<std::string> tlsIDs;
00113             for (std::set<NBTrafficLightDefinition*>::const_iterator it_tl = tlss.begin(); it_tl != tlss.end(); it_tl++) {
00114                 tlsIDs.insert((*it_tl)->getID());
00115             }
00116             std::vector<std::string> sortedIDs(tlsIDs.begin(), tlsIDs.end());
00117             sort(sortedIDs.begin(), sortedIDs.end());
00118             device.writeAttr(SUMO_ATTR_TLID, sortedIDs);
00119         }
00120         device.closeTag(true);
00121     }
00122     device.close();
00123 }
00124 
00125 
00126 void
00127 NWWriter_XML::writeEdgesAndConnections(const OptionsCont& oc, NBNodeCont& nc, NBEdgeCont& ec) {
00128     const GeoConvHelper& gch = GeoConvHelper::getFinal();
00129     bool useGeo = oc.exists("proj.plain-geo") && oc.getBool("proj.plain-geo");
00130     const bool geoAccuracy = useGeo || gch.usingInverseGeoProjection();
00131 
00132     OutputDevice& edevice = OutputDevice::getDevice(oc.getString("plain-output-prefix") + ".edg.xml");
00133     edevice.writeXMLHeader("edges", SUMOSAXAttributes::ENCODING, NWFrame::MAJOR_VERSION + " xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:noNamespaceSchemaLocation=\"http://sumo.sf.net/xsd/edges_file.xsd\"");
00134     OutputDevice& cdevice = OutputDevice::getDevice(oc.getString("plain-output-prefix") + ".con.xml");
00135     cdevice.writeXMLHeader("connections", SUMOSAXAttributes::ENCODING, NWFrame::MAJOR_VERSION + " xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:noNamespaceSchemaLocation=\"http://sumo.sf.net/xsd/connections_file.xsd\"");
00136     bool noNames = !oc.getBool("output.street-names");
00137     for (std::map<std::string, NBEdge*>::const_iterator i = ec.begin(); i != ec.end(); ++i) {
00138         // write the edge itself to the edges-files
00139         NBEdge* e = (*i).second;
00140         edevice.openTag(SUMO_TAG_EDGE);
00141         edevice.writeAttr(SUMO_ATTR_ID, e->getID());
00142         edevice.writeAttr(SUMO_ATTR_FROM, e->getFromNode()->getID());
00143         edevice.writeAttr(SUMO_ATTR_TO, e->getToNode()->getID());
00144         if (!noNames && e->getStreetName() != "") {
00145             edevice.writeAttr(SUMO_ATTR_NAME, e->getStreetName());
00146         }
00147         edevice.writeAttr(SUMO_ATTR_PRIORITY, e->getPriority());
00148         // write the type if given
00149         if (e->getTypeID() != "") {
00150             edevice.writeAttr(SUMO_ATTR_TYPE, e->getTypeID());
00151         }
00152         edevice.writeAttr(SUMO_ATTR_NUMLANES, e->getNumLanes());
00153         if (!e->hasLaneSpecificSpeed()) {
00154             edevice.writeAttr(SUMO_ATTR_SPEED, e->getSpeed());
00155         }
00156         // write non-default geometry
00157         if (!e->hasDefaultGeometry()) {
00158             PositionVector geom = e->getGeometry();
00159             if (useGeo) {
00160                 for (int i = 0; i < (int) geom.size(); i++) {
00161                     gch.cartesian2geo(geom[i]);
00162                 }
00163             }
00164             if (geoAccuracy) {
00165                 edevice.setPrecision(GEO_OUTPUT_ACCURACY);
00166             }
00167             edevice.writeAttr(SUMO_ATTR_SHAPE, geom);
00168             if (geoAccuracy) {
00169                 edevice.setPrecision();
00170             }
00171         }
00172         // write the spread type if not default ("right")
00173         if (e->getLaneSpreadFunction() != LANESPREAD_RIGHT) {
00174             edevice.writeAttr(SUMO_ATTR_SPREADTYPE, toString(e->getLaneSpreadFunction()));
00175         }
00176         // write the length if it was specified
00177         if (e->hasLoadedLength()) {
00178             edevice.writeAttr(SUMO_ATTR_LENGTH, e->getLoadedLength());
00179         }
00180         // some attributes can be set by edge default or per lane. Write as default if possible (efficiency)
00181         if (e->getWidth() != NBEdge::UNSPECIFIED_WIDTH && !e->hasLaneSpecificWidth()) {
00182             edevice.writeAttr(SUMO_ATTR_WIDTH, e->getWidth());
00183         }
00184         if (e->getOffset() != NBEdge::UNSPECIFIED_OFFSET && !e->hasLaneSpecificOffset()) {
00185             edevice.writeAttr(SUMO_ATTR_OFFSET, e->getOffset());
00186         }
00187         if (!e->needsLaneSpecificOutput()) {
00188             edevice.closeTag(true);
00189         } else {
00190             edevice << ">\n";
00191             for (unsigned int i = 0; i < e->getLanes().size(); ++i) {
00192                 const NBEdge::Lane& lane = e->getLanes()[i];
00193                 edevice.openTag(SUMO_TAG_LANE);
00194                 edevice.writeAttr(SUMO_ATTR_INDEX, i);
00195                 // write allowed lanes
00196                 if (lane.allowed.size() != 0) {
00197                     edevice.writeAttr(SUMO_ATTR_ALLOW, getVehicleClassNames(lane.allowed));
00198                 }
00199                 if (lane.notAllowed.size() != 0) {
00200                     edevice.writeAttr(SUMO_ATTR_DISALLOW, getVehicleClassNames(lane.notAllowed));
00201                 }
00202                 if (lane.preferred.size() != 0) {
00203                     edevice.writeAttr(SUMO_ATTR_PREFER, getVehicleClassNames(lane.preferred));
00204                 }
00205                 if (lane.width != NBEdge::UNSPECIFIED_WIDTH && e->hasLaneSpecificWidth()) {
00206                     edevice.writeAttr(SUMO_ATTR_WIDTH, lane.width);
00207                 }
00208                 if (lane.offset != NBEdge::UNSPECIFIED_OFFSET && e->hasLaneSpecificOffset()) {
00209                     edevice.writeAttr(SUMO_ATTR_OFFSET, lane.offset);
00210                 }
00211                 if (e->hasLaneSpecificSpeed()) {
00212                     edevice.writeAttr(SUMO_ATTR_SPEED, lane.speed);
00213                 }
00214                 edevice.closeTag(true);
00215             }
00216             edevice.closeTag();
00217         }
00218         // write this edge's connections to the connections-files
00219         e->sortOutgoingConnectionsByIndex();
00220         const std::vector<NBEdge::Connection> connections = e->getConnections();
00221         for (std::vector<NBEdge::Connection>::const_iterator c = connections.begin(); c != connections.end(); ++c) {
00222             NWWriter_SUMO::writeConnection(cdevice, *e, *c, false, NWWriter_SUMO::PLAIN);
00223         }
00224         if (connections.size() > 0) {
00225             cdevice << "\n";
00226         }
00227     }
00228 
00229     // write loaded prohibitions to the connections-file
00230     for (std::map<std::string, NBNode*>::const_iterator i = nc.begin(); i != nc.end(); ++i) {
00231         NWWriter_SUMO::writeProhibitions(cdevice, i->second->getProhibitions());
00232     }
00233     edevice.close();
00234     cdevice.close();
00235 }
00236 
00237 
00238 void
00239 NWWriter_XML::writeTrafficLights(const OptionsCont& oc, NBTrafficLightLogicCont& tc, NBEdgeCont& ec) {
00240     OutputDevice& device = OutputDevice::getDevice(oc.getString("plain-output-prefix") + ".tll.xml");
00241     device.writeXMLHeader("tlLogics", SUMOSAXAttributes::ENCODING, NWFrame::MAJOR_VERSION + " xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:noNamespaceSchemaLocation=\"http://sumo.sf.net/xsd/tllogic_file.xsd\"");
00242     NWWriter_SUMO::writeTrafficLights(device, tc);
00243     // we also need to remember the associations between tlLogics and connections
00244     // since the information in con.xml is insufficient
00245     for (std::map<std::string, NBEdge*>::const_iterator i = ec.begin(); i != ec.end(); ++i) {
00246         NBEdge* e = (*i).second;
00247         // write this edge's tl-controlled connections
00248         const std::vector<NBEdge::Connection> connections = e->getConnections();
00249         for (std::vector<NBEdge::Connection>::const_iterator c = connections.begin(); c != connections.end(); ++c) {
00250             if (c->tlID != "") {
00251                 NWWriter_SUMO::writeConnection(device, *e, *c, false, NWWriter_SUMO::TLL);
00252             }
00253         }
00254     }
00255     device.close();
00256 }
00257 /****************************************************************************/
00258 
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Friends Defines