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