SUMO - Simulation of Urban MObility
|
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 /****************************************************************************/