SUMO - Simulation of Urban MObility
|
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 writeNodes(oc, nb.getNodeCont()); 00064 writeEdgesAndConnections(oc, nb.getNodeCont(), nb.getEdgeCont()); 00065 writeTrafficLights(oc, nb.getTLLogicCont(), nb.getEdgeCont()); 00066 } 00067 if (oc.isSet("junctions.join-output")) { 00068 writeJoinedJunctions(oc, nb.getNodeCont()); 00069 } 00070 } 00071 00072 00073 void 00074 NWWriter_XML::writeNodes(const OptionsCont& oc, NBNodeCont& nc) { 00075 const GeoConvHelper& gch = GeoConvHelper::getFinal(); 00076 bool useGeo = oc.exists("proj.plain-geo") && oc.getBool("proj.plain-geo"); 00077 if (useGeo && !gch.usingGeoProjection()) { 00078 WRITE_WARNING("Ignoring option \"proj.plain-geo\" because no geo-conversion has been defined"); 00079 useGeo = false; 00080 } 00081 const bool geoAccuracy = useGeo || gch.usingInverseGeoProjection(); 00082 00083 OutputDevice& device = OutputDevice::getDevice(oc.getString("plain-output-prefix") + ".nod.xml"); 00084 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\""); 00085 00086 // write network offsets and projection to allow reconstruction of original coordinates 00087 if (!useGeo) { 00088 NWWriter_SUMO::writeLocation(device); 00089 } 00090 00091 // write nodes 00092 for (std::map<std::string, NBNode*>::const_iterator i = nc.begin(); i != nc.end(); ++i) { 00093 NBNode* n = (*i).second; 00094 device.openTag(SUMO_TAG_NODE); 00095 device.writeAttr(SUMO_ATTR_ID, n->getID()); 00096 // write position 00097 Position pos = n->getPosition(); 00098 if (useGeo) { 00099 gch.cartesian2geo(pos); 00100 } 00101 if (geoAccuracy) { 00102 device.setPrecision(GEO_OUTPUT_ACCURACY); 00103 } 00104 NWFrame::writePositionLong(pos, device); 00105 if (geoAccuracy) { 00106 device.setPrecision(); 00107 } 00108 00109 device.writeAttr(SUMO_ATTR_TYPE, toString(n->getType())); 00110 if (n->isTLControlled()) { 00111 const std::set<NBTrafficLightDefinition*> &tlss = n->getControllingTLS(); 00112 // set may contain multiple programs for the same id. 00113 // make sure ids are unique and sorted 00114 std::set<std::string> tlsIDs; 00115 for (std::set<NBTrafficLightDefinition*>::const_iterator it_tl = tlss.begin(); it_tl != tlss.end(); it_tl++) { 00116 tlsIDs.insert((*it_tl)->getID()); 00117 } 00118 std::vector<std::string> sortedIDs(tlsIDs.begin(), tlsIDs.end()); 00119 sort(sortedIDs.begin(), sortedIDs.end()); 00120 device.writeAttr(SUMO_ATTR_TLID, sortedIDs); 00121 } 00122 device.closeTag(true); 00123 } 00124 device.close(); 00125 } 00126 00127 00128 void 00129 NWWriter_XML::writeEdgesAndConnections(const OptionsCont& oc, NBNodeCont& nc, NBEdgeCont& ec) { 00130 const GeoConvHelper& gch = GeoConvHelper::getFinal(); 00131 bool useGeo = oc.exists("proj.plain-geo") && oc.getBool("proj.plain-geo"); 00132 const bool geoAccuracy = useGeo || gch.usingInverseGeoProjection(); 00133 00134 OutputDevice& edevice = OutputDevice::getDevice(oc.getString("plain-output-prefix") + ".edg.xml"); 00135 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\""); 00136 OutputDevice& cdevice = OutputDevice::getDevice(oc.getString("plain-output-prefix") + ".con.xml"); 00137 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\""); 00138 bool noNames = !oc.getBool("output.street-names"); 00139 for (std::map<std::string, NBEdge*>::const_iterator i = ec.begin(); i != ec.end(); ++i) { 00140 // write the edge itself to the edges-files 00141 NBEdge* e = (*i).second; 00142 edevice.openTag(SUMO_TAG_EDGE); 00143 edevice.writeAttr(SUMO_ATTR_ID, e->getID()); 00144 edevice.writeAttr(SUMO_ATTR_FROM, e->getFromNode()->getID()); 00145 edevice.writeAttr(SUMO_ATTR_TO, e->getToNode()->getID()); 00146 if (!noNames && e->getStreetName() != "") { 00147 edevice.writeAttr(SUMO_ATTR_NAME, e->getStreetName()); 00148 } 00149 edevice.writeAttr(SUMO_ATTR_PRIORITY, e->getPriority()); 00150 // write the type if given 00151 if (e->getTypeID() != "") { 00152 edevice.writeAttr(SUMO_ATTR_TYPE, e->getTypeID()); 00153 } 00154 edevice.writeAttr(SUMO_ATTR_NUMLANES, e->getNumLanes()); 00155 if (!e->hasLaneSpecificSpeed()) { 00156 edevice.writeAttr(SUMO_ATTR_SPEED, e->getSpeed()); 00157 } 00158 // write non-default geometry 00159 if (!e->hasDefaultGeometry()) { 00160 PositionVector geom = e->getGeometry(); 00161 if (useGeo) { 00162 for (int i = 0; i < (int) geom.size(); i++) { 00163 gch.cartesian2geo(geom[i]); 00164 } 00165 } 00166 if (geoAccuracy) { 00167 edevice.setPrecision(GEO_OUTPUT_ACCURACY); 00168 } 00169 edevice.writeAttr(SUMO_ATTR_SHAPE, geom); 00170 if (geoAccuracy) { 00171 edevice.setPrecision(); 00172 } 00173 } 00174 // write the spread type if not default ("right") 00175 if (e->getLaneSpreadFunction() != LANESPREAD_RIGHT) { 00176 edevice.writeAttr(SUMO_ATTR_SPREADTYPE, toString(e->getLaneSpreadFunction())); 00177 } 00178 // write the length if it was specified 00179 if (e->hasLoadedLength()) { 00180 edevice.writeAttr(SUMO_ATTR_LENGTH, e->getLoadedLength()); 00181 } 00182 // some attributes can be set by edge default or per lane. Write as default if possible (efficiency) 00183 if (e->getWidth() != NBEdge::UNSPECIFIED_WIDTH && !e->hasLaneSpecificWidth()) { 00184 edevice.writeAttr(SUMO_ATTR_WIDTH, e->getWidth()); 00185 } 00186 if (e->getOffset() != NBEdge::UNSPECIFIED_OFFSET && !e->hasLaneSpecificOffset()) { 00187 edevice.writeAttr(SUMO_ATTR_OFFSET, e->getOffset()); 00188 } 00189 if (!e->needsLaneSpecificOutput()) { 00190 edevice.closeTag(true); 00191 } else { 00192 edevice << ">\n"; 00193 for (unsigned int i = 0; i < e->getLanes().size(); ++i) { 00194 const NBEdge::Lane& lane = e->getLanes()[i]; 00195 edevice.openTag(SUMO_TAG_LANE); 00196 edevice.writeAttr(SUMO_ATTR_INDEX, i); 00197 // write allowed lanes 00198 NWWriter_SUMO::writePermissions(edevice, lane.permissions); 00199 NWWriter_SUMO::writePreferences(edevice, lane.preferred); 00200 // write other attributes 00201 if (lane.width != NBEdge::UNSPECIFIED_WIDTH && e->hasLaneSpecificWidth()) { 00202 edevice.writeAttr(SUMO_ATTR_WIDTH, lane.width); 00203 } 00204 if (lane.offset != NBEdge::UNSPECIFIED_OFFSET && e->hasLaneSpecificOffset()) { 00205 edevice.writeAttr(SUMO_ATTR_OFFSET, lane.offset); 00206 } 00207 if (e->hasLaneSpecificSpeed()) { 00208 edevice.writeAttr(SUMO_ATTR_SPEED, lane.speed); 00209 } 00210 edevice.closeTag(true); 00211 } 00212 edevice.closeTag(); 00213 } 00214 // write this edge's connections to the connections-files 00215 e->sortOutgoingConnectionsByIndex(); 00216 const std::vector<NBEdge::Connection> connections = e->getConnections(); 00217 for (std::vector<NBEdge::Connection>::const_iterator c = connections.begin(); c != connections.end(); ++c) { 00218 NWWriter_SUMO::writeConnection(cdevice, *e, *c, false, NWWriter_SUMO::PLAIN); 00219 } 00220 if (connections.size() > 0) { 00221 cdevice << "\n"; 00222 } 00223 } 00224 00225 // write loaded prohibitions to the connections-file 00226 for (std::map<std::string, NBNode*>::const_iterator i = nc.begin(); i != nc.end(); ++i) { 00227 NWWriter_SUMO::writeProhibitions(cdevice, i->second->getProhibitions()); 00228 } 00229 edevice.close(); 00230 cdevice.close(); 00231 } 00232 00233 00234 void 00235 NWWriter_XML::writeTrafficLights(const OptionsCont& oc, NBTrafficLightLogicCont& tc, NBEdgeCont& ec) { 00236 OutputDevice& device = OutputDevice::getDevice(oc.getString("plain-output-prefix") + ".tll.xml"); 00237 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\""); 00238 NWWriter_SUMO::writeTrafficLights(device, tc); 00239 // we also need to remember the associations between tlLogics and connections 00240 // since the information in con.xml is insufficient 00241 for (std::map<std::string, NBEdge*>::const_iterator i = ec.begin(); i != ec.end(); ++i) { 00242 NBEdge* e = (*i).second; 00243 // write this edge's tl-controlled connections 00244 const std::vector<NBEdge::Connection> connections = e->getConnections(); 00245 for (std::vector<NBEdge::Connection>::const_iterator c = connections.begin(); c != connections.end(); ++c) { 00246 if (c->tlID != "") { 00247 NWWriter_SUMO::writeConnection(device, *e, *c, false, NWWriter_SUMO::TLL); 00248 } 00249 } 00250 } 00251 device.close(); 00252 } 00253 00254 00255 void 00256 NWWriter_XML::writeJoinedJunctions(const OptionsCont& oc, NBNodeCont& nc) { 00257 OutputDevice& device = OutputDevice::getDevice(oc.getString("junctions.join-output")); 00258 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\""); 00259 const std::vector<std::set<std::string> >& clusters = nc.getJoinedClusters(); 00260 for (std::vector<std::set<std::string> >::const_iterator it = clusters.begin(); it != clusters.end(); it++) { 00261 assert((*it).size() > 0); 00262 device.openTag(SUMO_TAG_JOIN); 00263 // prepare string 00264 std::ostringstream oss; 00265 for (std::set<std::string>::iterator it_id = it->begin(); it_id != it->end(); it_id++) { 00266 oss << *it_id << " "; 00267 } 00268 // remove final space 00269 std::string ids = oss.str(); 00270 device.writeAttr(SUMO_ATTR_NODES, ids.substr(0, ids.size() - 1)); 00271 device.closeTag(true); 00272 } 00273 device.close(); 00274 } 00275 /****************************************************************************/ 00276