SUMO - Simulation of Urban MObility

NIImporter_MATSim.cpp

Go to the documentation of this file.
00001 /****************************************************************************/
00007 // Importer for networks stored in MATSim 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 <set>
00030 #include <functional>
00031 #include <sstream>
00032 #include <utils/xml/SUMOSAXHandler.h>
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/geom/GeoConvHelper.h>
00040 #include <utils/options/OptionsCont.h>
00041 #include <utils/common/FileHelpers.h>
00042 #include <utils/common/StringTokenizer.h>
00043 #include <utils/common/TplConvert.h>
00044 #include <utils/xml/XMLSubSys.h>
00045 #include "NILoader.h"
00046 #include "NIImporter_MATSim.h"
00047 
00048 #ifdef CHECK_MEMORY_LEAKS
00049 #include <foreign/nvwa/debug_new.h>
00050 #endif // CHECK_MEMORY_LEAKS
00051 
00052 
00053 
00054 // ===========================================================================
00055 // static variables
00056 // ===========================================================================
00057 StringBijection<int>::Entry NIImporter_MATSim::matsimTags[] = {
00058     { "network",          NIImporter_MATSim::MATSIM_TAG_NETWORK },
00059     { "node",             NIImporter_MATSim::MATSIM_TAG_NODE },
00060     { "link",             NIImporter_MATSim::MATSIM_TAG_LINK },
00061     { "links",            NIImporter_MATSim::MATSIM_TAG_LINKS },
00062     { "",                 NIImporter_MATSim::MATSIM_TAG_NOTHING }
00063 };
00064 
00065 
00066 StringBijection<int>::Entry NIImporter_MATSim::matsimAttrs[] = {
00067     { "id",             NIImporter_MATSim::MATSIM_ATTR_ID },
00068     { "x",              NIImporter_MATSim::MATSIM_ATTR_X },
00069     { "y",              NIImporter_MATSim::MATSIM_ATTR_Y },
00070     { "from",           NIImporter_MATSim::MATSIM_ATTR_FROM },
00071     { "to",             NIImporter_MATSim::MATSIM_ATTR_TO },
00072     { "length",         NIImporter_MATSim::MATSIM_ATTR_LENGTH },
00073     { "freespeed",      NIImporter_MATSim::MATSIM_ATTR_FREESPEED },
00074     { "capacity",       NIImporter_MATSim::MATSIM_ATTR_CAPACITY },
00075     { "permlanes",      NIImporter_MATSim::MATSIM_ATTR_PERMLANES },
00076     { "oneway",         NIImporter_MATSim::MATSIM_ATTR_ONEWAY },
00077     { "modes",          NIImporter_MATSim::MATSIM_ATTR_MODES },
00078     { "origid",         NIImporter_MATSim::MATSIM_ATTR_ORIGID },
00079     { "capperiod",      NIImporter_MATSim::MATSIM_ATTR_CAPPERIOD },
00080     { "capDivider",     NIImporter_MATSim::MATSIM_ATTR_CAPDIVIDER },
00081 
00082     { "",               NIImporter_MATSim::MATSIM_ATTR_NOTHING }
00083 };
00084 
00085 
00086 // ===========================================================================
00087 // method definitions
00088 // ===========================================================================
00089 // ---------------------------------------------------------------------------
00090 // static methods
00091 // ---------------------------------------------------------------------------
00092 void
00093 NIImporter_MATSim::loadNetwork(const OptionsCont& oc, NBNetBuilder& nb) {
00094     // check whether the option is set (properly)
00095     if (!oc.isSet("matsim-files")) {
00096         return;
00097     }
00098     /* Parse file(s)
00099      * Each file is parsed twice: first for nodes, second for edges. */
00100     std::vector<std::string> files = oc.getStringVector("matsim-files");
00101     // load nodes, first
00102     NodesHandler nodesHandler(nb.getNodeCont());
00103     for (std::vector<std::string>::const_iterator file=files.begin(); file!=files.end(); ++file) {
00104         // nodes
00105         if (!FileHelpers::exists(*file)) {
00106             WRITE_ERROR("Could not open matsim-file '" + *file + "'.");
00107             return;
00108         }
00109         nodesHandler.setFileName(*file);
00110         PROGRESS_BEGIN_MESSAGE("Parsing nodes from matsim-file '" + *file + "'");
00111         if (!XMLSubSys::runParser(nodesHandler, *file)) {
00112             return;
00113         }
00114         PROGRESS_DONE_MESSAGE();
00115     }
00116     // load edges, then
00117     EdgesHandler edgesHandler(nb.getNodeCont(), nb.getEdgeCont(), oc.getBool("matsim.keep-length"),
00118                               oc.getBool("matsim.lanes-from-capacity"), NBCapacity2Lanes(oc.getFloat("lanes-from-capacity.norm")));
00119     for (std::vector<std::string>::const_iterator file=files.begin(); file!=files.end(); ++file) {
00120         // edges
00121         edgesHandler.setFileName(*file);
00122         PROGRESS_BEGIN_MESSAGE("Parsing edges from matsim-file '" + *file + "'");
00123         XMLSubSys::runParser(edgesHandler, *file);
00124         PROGRESS_DONE_MESSAGE();
00125     }
00126 }
00127 
00128 
00129 // ---------------------------------------------------------------------------
00130 // definitions of NIImporter_MATSim::NodesHandler-methods
00131 // ---------------------------------------------------------------------------
00132 NIImporter_MATSim::NodesHandler::NodesHandler(NBNodeCont& toFill) throw()
00133     : GenericSAXHandler(matsimTags, MATSIM_TAG_NOTHING,
00134                         matsimAttrs, MATSIM_ATTR_NOTHING,
00135                         "matsim - file"), myNodeCont(toFill) {
00136 }
00137 
00138 
00139 NIImporter_MATSim::NodesHandler::~NodesHandler() throw() {}
00140 
00141 
00142 void
00143 NIImporter_MATSim::NodesHandler::myStartElement(int element, const SUMOSAXAttributes& attrs) throw(ProcessError) {
00144     if (element != MATSIM_TAG_NODE) {
00145         return;
00146     }
00147     // get the id, report a warning if not given or empty...
00148     bool ok = true;
00149     std::string id = attrs.getStringReporting(MATSIM_ATTR_ID, 0, ok);
00150     SUMOReal x = attrs.getSUMORealReporting(MATSIM_ATTR_X, id.c_str(), ok);
00151     SUMOReal y = attrs.getSUMORealReporting(MATSIM_ATTR_Y, id.c_str(), ok);
00152     if (!ok) {
00153         return;
00154     }
00155     Position pos(x, y);
00156     if (!NILoader::transformCoordinates(pos)) {
00157         WRITE_ERROR("Unable to project coordinates for node '" + id + "'.");
00158     }
00159     NBNode* node = new NBNode(id, pos);
00160     if (!myNodeCont.insert(node)) {
00161         delete node;
00162         WRITE_ERROR("Could not add node '" + id + "'. Probably declared twice.");
00163     }
00164 }
00165 
00166 
00167 
00168 // ---------------------------------------------------------------------------
00169 // definitions of NIImporter_MATSim::EdgesHandler-methods
00170 // ---------------------------------------------------------------------------
00171 NIImporter_MATSim::EdgesHandler::EdgesHandler(const NBNodeCont& nc, NBEdgeCont& toFill,
00172         bool keepEdgeLengths, bool lanesFromCapacity,
00173         NBCapacity2Lanes capacity2Lanes) throw()
00174     : GenericSAXHandler(matsimTags, MATSIM_TAG_NOTHING,
00175                         matsimAttrs, MATSIM_ATTR_NOTHING, "matsim - file"),
00176     myNodeCont(nc), myEdgeCont(toFill), myCapacityNorm(3600),
00177     myKeepEdgeLengths(keepEdgeLengths), myLanesFromCapacity(lanesFromCapacity),
00178     myCapacity2Lanes(capacity2Lanes) {
00179 }
00180 
00181 
00182 NIImporter_MATSim::EdgesHandler::~EdgesHandler() throw() {
00183 }
00184 
00185 
00186 void
00187 NIImporter_MATSim::EdgesHandler::myStartElement(int element,
00188         const SUMOSAXAttributes& attrs) throw(ProcessError) {
00189     bool ok = true;
00190     if (element==MATSIM_TAG_NETWORK) {
00191         if (attrs.hasAttribute(MATSIM_ATTR_CAPDIVIDER)) {
00192             int capDivider = attrs.getIntReporting(MATSIM_ATTR_CAPDIVIDER, "network", ok);
00193             if (ok) {
00194                 myCapacityNorm = (SUMOReal)(capDivider*3600);
00195             }
00196         }
00197     }
00198     if (element==MATSIM_TAG_LINKS) {
00199         bool ok = true;
00200         std::string capperiod = attrs.getStringReporting(MATSIM_ATTR_CAPPERIOD, "links", ok);
00201         StringTokenizer st(capperiod, ":");
00202         if (st.size()!=3) {
00203             WRITE_ERROR("Bogus capacity period format; requires 'hh:mm:ss'.");
00204             return;
00205         }
00206         try {
00207             int hours = TplConvert<char>::_2int(st.next().c_str());
00208             int minutes = TplConvert<char>::_2int(st.next().c_str());
00209             int seconds = TplConvert<char>::_2int(st.next().c_str());
00210             myCapacityNorm = (SUMOReal)(hours*3600+minutes*60+seconds);
00211         } catch (NumberFormatException&) {
00212         } catch (EmptyData&) {
00213         }
00214         return;
00215     }
00216 
00217     // parse "link" elements
00218     if (element!=MATSIM_TAG_LINK) {
00219         return;
00220     }
00221     std::string id = attrs.getStringReporting(MATSIM_ATTR_ID, 0, ok);
00222     std::string fromNodeID = attrs.getStringReporting(MATSIM_ATTR_FROM, id.c_str(), ok);
00223     std::string toNodeID = attrs.getStringReporting(MATSIM_ATTR_TO, id.c_str(), ok);
00224     SUMOReal length = attrs.getSUMORealReporting(MATSIM_ATTR_LENGTH, id.c_str(), ok); // override computed?
00225     SUMOReal freeSpeed = attrs.getSUMORealReporting(MATSIM_ATTR_FREESPEED, id.c_str(), ok); //
00226     SUMOReal capacity = attrs.getSUMORealReporting(MATSIM_ATTR_CAPACITY, id.c_str(), ok); // override permLanes?
00227     SUMOReal permLanes = attrs.getSUMORealReporting(MATSIM_ATTR_PERMLANES, id.c_str(), ok);
00228     //bool oneWay = attrs.getOptBoolReporting(MATSIM_ATTR_ONEWAY, id.c_str(), ok, true); // mandatory?
00229     std::string modes = attrs.getOptStringReporting(MATSIM_ATTR_MODES, id.c_str(), ok, ""); // which values?
00230     std::string origid = attrs.getOptStringReporting(MATSIM_ATTR_ORIGID, id.c_str(), ok, "");
00231     NBNode* fromNode = myNodeCont.retrieve(fromNodeID);
00232     NBNode* toNode = myNodeCont.retrieve(toNodeID);
00233     if (fromNode==0) {
00234         WRITE_ERROR("Could not find from-node for edge '" + id + "'.");
00235     }
00236     if (toNode==0) {
00237         WRITE_ERROR("Could not find to-node for edge '" + id + "'.");
00238     }
00239     if (fromNode==0||toNode==0) {
00240         return;
00241     }
00242     if (myLanesFromCapacity) {
00243         permLanes = myCapacity2Lanes.get(capacity);
00244     }
00245     NBEdge* edge = new NBEdge(id, fromNode, toNode, "", freeSpeed, (unsigned int) permLanes, -1, -1, -1);
00246     if (myKeepEdgeLengths) {
00247         edge->setLoadedLength(length);
00248     }
00249     if (!myEdgeCont.insert(edge)) {
00250         delete edge;
00251         WRITE_ERROR("Could not add edge '" + id + "'. Probably declared twice.");
00252     }
00253 }
00254 
00255 
00256 /****************************************************************************/
00257 
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Friends Defines