|
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 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