SUMO - Simulation of Urban MObility
NILoader.cpp
Go to the documentation of this file.
00001 /****************************************************************************/
00010 // Perfoms network import
00011 /****************************************************************************/
00012 // SUMO, Simulation of Urban MObility; see http://sumo.sourceforge.net/
00013 // Copyright (C) 2001-2012 DLR (http://www.dlr.de/) and contributors
00014 /****************************************************************************/
00015 //
00016 //   This file is part of SUMO.
00017 //   SUMO is free software: you can redistribute it and/or modify
00018 //   it under the terms of the GNU General Public License as published by
00019 //   the Free Software Foundation, either version 3 of the License, or
00020 //   (at your option) any later version.
00021 //
00022 /****************************************************************************/
00023 
00024 
00025 // ===========================================================================
00026 // included modules
00027 // ===========================================================================
00028 #ifdef _MSC_VER
00029 #include <windows_config.h>
00030 #else
00031 #include <config.h>
00032 #endif
00033 
00034 #include <string>
00035 #include <utils/common/UtilExceptions.h>
00036 #include <utils/common/MsgHandler.h>
00037 #include <utils/options/OptionsCont.h>
00038 #include <utils/options/Option.h>
00039 #include <utils/common/FileHelpers.h>
00040 #include <utils/common/StringUtils.h>
00041 #include <utils/common/ToString.h>
00042 #include <netbuild/NBTypeCont.h>
00043 #include <netbuild/NBNodeCont.h>
00044 #include <netbuild/NBEdgeCont.h>
00045 #include <netbuild/NBNetBuilder.h>
00046 #include <utils/xml/SUMOSAXHandler.h>
00047 #include <netimport/NIXMLEdgesHandler.h>
00048 #include <netimport/NIXMLNodesHandler.h>
00049 #include <netimport/NIXMLTrafficLightsHandler.h>
00050 #include <netimport/NIXMLTypesHandler.h>
00051 #include <netimport/NIXMLConnectionsHandler.h>
00052 #include <netimport/NIImporter_DlrNavteq.h>
00053 #include <netimport/NIImporter_VISUM.h>
00054 #include <netimport/vissim/NIImporter_Vissim.h>
00055 #include <netimport/NIImporter_ArcView.h>
00056 #include <netimport/NIImporter_SUMO.h>
00057 #include <netimport/NIImporter_RobocupRescue.h>
00058 #include <netimport/NIImporter_OpenStreetMap.h>
00059 #include <netimport/NIImporter_OpenDrive.h>
00060 #include <netimport/NIImporter_MATSim.h>
00061 #include <netimport/NIImporter_ITSUMO.h>
00062 #include <utils/xml/XMLSubSys.h>
00063 #include "NILoader.h"
00064 #include <utils/common/TplConvert.h>
00065 #include <utils/geom/GeoConvHelper.h>
00066 
00067 #ifdef HAVE_MESOSIM
00068 #include <internal/HeightMapper.h>
00069 #endif
00070 
00071 #ifdef CHECK_MEMORY_LEAKS
00072 #include <foreign/nvwa/debug_new.h>
00073 #endif // CHECK_MEMORY_LEAKS
00074 
00075 
00076 // ===========================================================================
00077 // method definitions
00078 // ===========================================================================
00079 NILoader::NILoader(NBNetBuilder& nb)
00080     : myNetBuilder(nb) {}
00081 
00082 
00083 NILoader::~NILoader() {}
00084 
00085 
00086 void
00087 NILoader::load(OptionsCont& oc) {
00088     // build the projection
00089     if (!GeoConvHelper::init(oc)) {
00090         throw ProcessError("Could not build projection!");
00091     }
00092     // load types first
00093     NIXMLTypesHandler* handler =
00094         new NIXMLTypesHandler(myNetBuilder.getTypeCont());
00095     loadXMLType(handler, oc.getStringVector("type-files"), "types");
00096     // try to load height data so it is ready for use by other importers
00097 #ifdef HAVE_MESOSIM
00098     HeightMapper::loadIfSet(oc);
00099 #endif
00100     // try to load using different methods
00101     NIImporter_SUMO::loadNetwork(oc, myNetBuilder);
00102     NIImporter_RobocupRescue::loadNetwork(oc, myNetBuilder);
00103     NIImporter_OpenStreetMap::loadNetwork(oc, myNetBuilder);
00104     NIImporter_VISUM::loadNetwork(oc, myNetBuilder);
00105     NIImporter_ArcView::loadNetwork(oc, myNetBuilder);
00106     NIImporter_Vissim::loadNetwork(oc, myNetBuilder);
00107     NIImporter_DlrNavteq::loadNetwork(oc, myNetBuilder);
00108     NIImporter_OpenDrive::loadNetwork(oc, myNetBuilder);
00109     NIImporter_MATSim::loadNetwork(oc, myNetBuilder);
00110     NIImporter_ITSUMO::loadNetwork(oc, myNetBuilder);
00111     loadXML(oc);
00112     // check the loaded structures
00113     if (myNetBuilder.getNodeCont().size() == 0) {
00114         throw ProcessError("No nodes loaded.");
00115     }
00116     if (myNetBuilder.getEdgeCont().size() == 0) {
00117         throw ProcessError("No edges loaded.");
00118     }
00119     // report loaded structures
00120     WRITE_MESSAGE(" Import done:");
00121     if (myNetBuilder.getDistrictCont().size() > 0) {
00122         WRITE_MESSAGE("   " + toString(myNetBuilder.getDistrictCont().size()) + " districts loaded.");
00123     }
00124     WRITE_MESSAGE("   " + toString(myNetBuilder.getNodeCont().size()) + " nodes loaded.");
00125     if (myNetBuilder.getTypeCont().size() > 0) {
00126         WRITE_MESSAGE("   " + toString(myNetBuilder.getTypeCont().size()) + " types loaded.");
00127     }
00128     WRITE_MESSAGE("   " + toString(myNetBuilder.getEdgeCont().size()) + " edges loaded.");
00129     if (myNetBuilder.getEdgeCont().getNoEdgeSplits() > 0) {
00130         WRITE_MESSAGE("The split of edges was performed " + toString(myNetBuilder.getEdgeCont().getNoEdgeSplits()) + " times.");
00131     }
00132     if (GeoConvHelper::getProcessing().usingGeoProjection()) {
00133         WRITE_MESSAGE("Proj projection parameters used: '" + GeoConvHelper::getProcessing().getProjString() + "'.");
00134     }
00135 }
00136 
00137 
00138 /* -------------------------------------------------------------------------
00139  * file loading methods
00140  * ----------------------------------------------------------------------- */
00141 void
00142 NILoader::loadXML(OptionsCont& oc) {
00143     // load nodes
00144     loadXMLType(new NIXMLNodesHandler(myNetBuilder.getNodeCont(),
00145                                       myNetBuilder.getTLLogicCont(), oc),
00146                 oc.getStringVector("node-files"), "nodes");
00147     // load the edges
00148     loadXMLType(new NIXMLEdgesHandler(myNetBuilder.getNodeCont(),
00149                                       myNetBuilder.getEdgeCont(),
00150                                       myNetBuilder.getTypeCont(),
00151                                       myNetBuilder.getDistrictCont(), oc),
00152                 oc.getStringVector("edge-files"), "edges");
00153     // load the connections
00154     loadXMLType(new NIXMLConnectionsHandler(myNetBuilder.getEdgeCont()),
00155                 oc.getStringVector("connection-files"), "connections");
00156     // load traffic lights (needs to come last, references loaded edges and connections)
00157     loadXMLType(new NIXMLTrafficLightsHandler(
00158                     myNetBuilder.getTLLogicCont(), myNetBuilder.getEdgeCont()),
00159                 oc.getStringVector("tllogic-files"), "traffic lights");
00160 }
00161 
00162 
00163 void
00164 NILoader::loadXMLType(SUMOSAXHandler* handler, const std::vector<std::string> &files,
00165                       const std::string& type) {
00166     // build parser
00167     SAX2XMLReader* parser = XMLSubSys::getSAXReader(*handler);
00168     std::string exceptMsg = "";
00169     // start the parsing
00170     try {
00171         for (std::vector<std::string>::const_iterator file = files.begin(); file != files.end(); ++file) {
00172             if (!FileHelpers::exists(*file)) {
00173                 WRITE_ERROR("Could not open " + type + "-file '" + *file + "'.");
00174                 exceptMsg = "Process Error";
00175                 continue;
00176             }
00177             handler->setFileName(*file);
00178             PROGRESS_BEGIN_MESSAGE("Parsing " + type + " from '" + *file + "'");
00179             parser->parse(file->c_str());
00180             PROGRESS_DONE_MESSAGE();
00181         }
00182     } catch (const XMLException& toCatch) {
00183         exceptMsg = TplConvert<XMLCh>::_2str(toCatch.getMessage())
00184                     + "\n  The " + type  + " could not be loaded from '" + handler->getFileName() + "'.";
00185     } catch (const ProcessError& toCatch) {
00186         exceptMsg = std::string(toCatch.what()) + "\n  The " + type  + " could not be loaded from '" + handler->getFileName() + "'.";
00187     } catch (...) {
00188         exceptMsg = "The " + type  + " could not be loaded from '" + handler->getFileName() + "'.";
00189     }
00190     delete parser;
00191     delete handler;
00192     if (exceptMsg != "") {
00193         throw ProcessError(exceptMsg);
00194     }
00195 }
00196 
00197 
00198 bool
00199 NILoader::transformCoordinates(Position& from, bool includeInBoundary, GeoConvHelper* from_srs) {
00200     Position orig(from);
00201     bool ok = GeoConvHelper::getProcessing().x2cartesian(from, includeInBoundary);
00202 #ifdef HAVE_MESOSIM
00203     if (ok) {
00204         const HeightMapper& hm = HeightMapper::get();
00205         if (hm.ready()) {
00206             if (from_srs != 0 && from_srs->usingGeoProjection()) {
00207                 from_srs->cartesian2geo(orig);
00208             }
00209             SUMOReal z = hm.getZ(orig);
00210             from = Position(from.x(), from.y(), z);
00211         }
00212     }
00213 #endif
00214     return ok;
00215 }
00216 
00217 
00218 bool
00219 NILoader::transformCoordinates(PositionVector& from, bool includeInBoundary, GeoConvHelper* from_srs) {
00220     const SUMOReal maxLength = OptionsCont::getOptions().getFloat("geometry.max-segment-length");
00221     if (maxLength > 0 && from.size() > 1) {
00222         // transformation to cartesian coordinates must happen before we can check segment length
00223         PositionVector copy = from;
00224         for (int i = 0; i < (int) from.size(); i++) {
00225             transformCoordinates(copy[i], false);
00226         }
00227         // check lengths and insert new points where needed (in the original
00228         // coordinate system)
00229         int inserted = 0;
00230         for (int i = 0; i < (int)copy.size() - 1; i++) {
00231             Position start = from[i + inserted];
00232             Position end = from[i + inserted + 1];
00233             SUMOReal length = copy[i].distanceTo(copy[i + 1]);
00234             const Position step = (end - start) * (maxLength / length);
00235             int steps = 0;
00236             while (length > maxLength) {
00237                 length -= maxLength;
00238                 steps++;
00239                 from.insertAt(i + inserted + 1, start + (step * steps));
00240                 inserted++;
00241             }
00242         }
00243         // now perform the transformation again so that height mapping can be
00244         // performed for the new points
00245     }
00246     bool ok = true;
00247     for (int i = 0; i < (int) from.size(); i++) {
00248         ok = ok && transformCoordinates(from[i], includeInBoundary, from_srs);
00249     }
00250     return ok;
00251 }
00252 /****************************************************************************/
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Friends Defines