|
SUMO - Simulation of Urban MObility
|
00001 /****************************************************************************/ 00007 // Exporter writing networks using XML (native input) 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 <algorithm> 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/common/ToString.h> 00037 #include <utils/options/OptionsCont.h> 00038 #include <utils/iodevices/OutputDevice.h> 00039 #include <utils/geom/GeoConvHelper.h> 00040 #include "NWFrame.h" 00041 #include "NWWriter_SUMO.h" 00042 #include "NWWriter_XML.h" 00043 00044 #ifdef CHECK_MEMORY_LEAKS 00045 #include <foreign/nvwa/debug_new.h> 00046 #endif // CHECK_MEMORY_LEAKS 00047 00048 00049 00050 // =========================================================================== 00051 // method definitions 00052 // =========================================================================== 00053 // --------------------------------------------------------------------------- 00054 // static methods 00055 // --------------------------------------------------------------------------- 00056 void 00057 NWWriter_XML::writeNetwork(const OptionsCont& oc, NBNetBuilder& nb) { 00058 // check whether a matsim-file shall be generated 00059 if (!oc.isSet("plain-output-prefix")) { 00060 return; 00061 } 00062 writeNodes(oc, nb.getNodeCont()); 00063 writeEdgesAndConnections(oc, nb.getNodeCont(), nb.getEdgeCont()); 00064 writeTrafficLights(oc, nb.getTLLogicCont(), nb.getEdgeCont()); 00065 } 00066 00067 00068 void 00069 NWWriter_XML::writeNodes(const OptionsCont& oc, NBNodeCont& nc) { 00070 // write nodes 00071 OutputDevice& device = OutputDevice::getDevice(oc.getString("plain-output-prefix") + ".nod.xml"); 00072 device.writeXMLHeader("nodes", " encoding=\"iso-8859-1\"", "version=\"0.13\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:noNamespaceSchemaLocation=\"http://sumo.sf.net/xsd/nodes_file.xsd\""); 00073 for (std::map<std::string, NBNode*>::const_iterator i=nc.begin(); i!=nc.end(); ++i) { 00074 NBNode* n = (*i).second; 00075 device.openTag(SUMO_TAG_NODE); 00076 device.writeAttr(SUMO_ATTR_ID, n->getID()); 00077 if (GeoConvHelper::getOutputInstance().usingInverseGeoProjection()) { 00078 device.setPrecision(GEO_OUTPUT_ACCURACY); 00079 } 00080 NWFrame::writePositionLong(n->getPosition(), device); 00081 device.setPrecision(); 00082 device.writeAttr(SUMO_ATTR_TYPE, toString(n->getType())); 00083 if (n->isTLControlled()) { 00084 const std::set<NBTrafficLightDefinition*> &tlss = n->getControllingTLS(); 00085 // set may contain multiple programs for the same id. 00086 // make sure ids are unique and sorted 00087 std::set<std::string> tlsIDs; 00088 for (std::set<NBTrafficLightDefinition*>::const_iterator it_tl =tlss.begin(); it_tl!=tlss.end(); it_tl++) { 00089 tlsIDs.insert((*it_tl)->getID()); 00090 } 00091 std::vector<std::string> sortedIDs(tlsIDs.begin(), tlsIDs.end()); 00092 sort(sortedIDs.begin(), sortedIDs.end()); 00093 device.writeAttr(SUMO_ATTR_TLID, sortedIDs); 00094 } 00095 device.closeTag(true); 00096 } 00097 device.close(); 00098 } 00099 00100 00101 void 00102 NWWriter_XML::writeEdgesAndConnections(const OptionsCont& oc, NBNodeCont& nc, NBEdgeCont& ec) { 00103 OutputDevice& edevice = OutputDevice::getDevice(oc.getString("plain-output-prefix") + ".edg.xml"); 00104 edevice.writeXMLHeader("edges", " encoding=\"iso-8859-1\"", "version=\"0.13\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:noNamespaceSchemaLocation=\"http://sumo.sf.net/xsd/edges_file.xsd\""); 00105 OutputDevice& cdevice = OutputDevice::getDevice(oc.getString("plain-output-prefix") + ".con.xml"); 00106 cdevice.writeXMLHeader("connections", " encoding=\"iso-8859-1\"", "version=\"0.13\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:noNamespaceSchemaLocation=\"http://sumo.sf.net/xsd/connections_file.xsd\""); 00107 bool noNames = !oc.getBool("output.street-names"); 00108 for (std::map<std::string, NBEdge*>::const_iterator i=ec.begin(); i!=ec.end(); ++i) { 00109 // write the edge itself to the edges-files 00110 NBEdge* e = (*i).second; 00111 edevice.openTag(SUMO_TAG_EDGE); 00112 edevice.writeAttr(SUMO_ATTR_ID, e->getID()); 00113 edevice.writeAttr(SUMO_ATTR_FROM, e->getFromNode()->getID()); 00114 edevice.writeAttr(SUMO_ATTR_TO, e->getToNode()->getID()); 00115 if (!noNames && e->getStreetName() != "") { 00116 edevice.writeAttr(SUMO_ATTR_NAME, e->getStreetName()); 00117 } 00118 edevice.writeAttr(SUMO_ATTR_PRIORITY, e->getPriority()); 00119 // write the type if given 00120 if (e->getTypeID() != "") { 00121 edevice.writeAttr(SUMO_ATTR_TYPE, e->getTypeID()); 00122 } 00123 edevice.writeAttr(SUMO_ATTR_NUMLANES, e->getNumLanes()); 00124 if (!e->hasLaneSpecificSpeed()) { 00125 edevice.writeAttr(SUMO_ATTR_SPEED, e->getSpeed()); 00126 } 00127 // write non-default geometry 00128 if (!e->hasDefaultGeometry()) { 00129 if (GeoConvHelper::getOutputInstance().usingInverseGeoProjection()) { 00130 edevice.setPrecision(GEO_OUTPUT_ACCURACY); 00131 } 00132 edevice.writeAttr(SUMO_ATTR_SHAPE, e->getGeometry()); 00133 edevice.setPrecision(); 00134 } 00135 // write the spread type if not default ("right") 00136 if (e->getLaneSpreadFunction()!=LANESPREAD_RIGHT) { 00137 edevice.writeAttr(SUMO_ATTR_SPREADTYPE, toString(e->getLaneSpreadFunction())); 00138 } 00139 // write the length if it was specified 00140 if (e->hasLoadedLength()) { 00141 edevice.writeAttr(SUMO_ATTR_LENGTH, e->getLoadedLength()); 00142 } 00143 // some attributes can be set by edge default or per lane. Write as default if possible (efficiency) 00144 if (e->getWidth() != NBEdge::UNSPECIFIED_WIDTH && !e->hasLaneSpecificWidth()) { 00145 edevice.writeAttr(SUMO_ATTR_WIDTH, e->getWidth()); 00146 } 00147 if (e->getOffset() != NBEdge::UNSPECIFIED_OFFSET && !e->hasLaneSpecificOffset()) { 00148 edevice.writeAttr(SUMO_ATTR_OFFSET, e->getOffset()); 00149 } 00150 if (!e->needsLaneSpecificOutput()) { 00151 edevice.closeTag(true); 00152 } else { 00153 edevice << ">\n"; 00154 for (unsigned int i=0; i<e->getLanes().size(); ++i) { 00155 const NBEdge::Lane& lane = e->getLanes()[i]; 00156 edevice.openTag(SUMO_TAG_LANE); 00157 edevice.writeAttr(SUMO_ATTR_INDEX, i); 00158 // write allowed lanes 00159 if (lane.allowed.size()!=0) { 00160 edevice.writeAttr(SUMO_ATTR_ALLOW, getVehicleClassNames(lane.allowed)); 00161 } 00162 if (lane.notAllowed.size()!=0) { 00163 edevice.writeAttr(SUMO_ATTR_DISALLOW, getVehicleClassNames(lane.notAllowed)); 00164 } 00165 if (lane.preferred.size()!=0) { 00166 edevice.writeAttr(SUMO_ATTR_PREFER, getVehicleClassNames(lane.preferred)); 00167 } 00168 if (lane.width != NBEdge::UNSPECIFIED_WIDTH && e->hasLaneSpecificWidth()) { 00169 edevice.writeAttr(SUMO_ATTR_WIDTH, lane.width); 00170 } 00171 if (lane.offset != NBEdge::UNSPECIFIED_OFFSET && e->hasLaneSpecificOffset()) { 00172 edevice.writeAttr(SUMO_ATTR_OFFSET, lane.offset); 00173 } 00174 if (e->hasLaneSpecificSpeed()) { 00175 edevice.writeAttr(SUMO_ATTR_SPEED, lane.speed); 00176 } 00177 edevice.closeTag(true); 00178 } 00179 edevice.closeTag(); 00180 } 00181 // write this edge's connections to the connections-files 00182 unsigned int noLanes = e->getNumLanes(); 00183 e->sortOutgoingConnectionsByIndex(); 00184 const std::vector<NBEdge::Connection> connections = e->getConnections(); 00185 for (std::vector<NBEdge::Connection>::const_iterator c=connections.begin(); c!=connections.end(); ++c) { 00186 NWWriter_SUMO::writeConnection(cdevice, *e, *c, false, NWWriter_SUMO::PLAIN); 00187 } 00188 if (connections.size() > 0) { 00189 cdevice << "\n"; 00190 } 00191 } 00192 00193 // write loaded prohibitions to the connections-file 00194 for (std::map<std::string, NBNode*>::const_iterator i=nc.begin(); i!=nc.end(); ++i) { 00195 NWWriter_SUMO::writeProhibitions(cdevice, i->second->getProhibitions()); 00196 } 00197 edevice.close(); 00198 cdevice.close(); 00199 } 00200 00201 00202 void 00203 NWWriter_XML::writeTrafficLights(const OptionsCont& oc, NBTrafficLightLogicCont& tc, NBEdgeCont& ec) { 00204 OutputDevice& device = OutputDevice::getDevice(oc.getString("plain-output-prefix") + ".tll.xml"); 00205 device.writeXMLHeader("tlLogics", " encoding=\"iso-8859-1\"", "version=\"0.13\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:noNamespaceSchemaLocation=\"http://sumo.sf.net/xsd/nodes_file.xsd\""); 00206 NWWriter_SUMO::writeTrafficLights(device, tc); 00207 // we also need to remember the associations between tlLogics and connections 00208 // since the information in con.xml is insufficient 00209 for (std::map<std::string, NBEdge*>::const_iterator i=ec.begin(); i!=ec.end(); ++i) { 00210 NBEdge* e = (*i).second; 00211 // write this edge's tl-controlled connections 00212 const std::vector<NBEdge::Connection> connections = e->getConnections(); 00213 for (std::vector<NBEdge::Connection>::const_iterator c=connections.begin(); c!=connections.end(); ++c) { 00214 if (c->tlID != "") { 00215 NWWriter_SUMO::writeConnection(device, *e, *c, false, NWWriter_SUMO::TLL); 00216 } 00217 } 00218 } 00219 device.close(); 00220 } 00221 /****************************************************************************/ 00222