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