SUMO - Simulation of Urban MObility
NIImporter_DlrNavteq.cpp
Go to the documentation of this file.
00001 /****************************************************************************/
00009 // Importer for networks stored in Elmar's 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 
00033 #include <string>
00034 #include <sstream>
00035 #include <utils/importio/LineHandler.h>
00036 #include <utils/common/StringTokenizer.h>
00037 #include <utils/common/MsgHandler.h>
00038 #include <utils/common/UtilExceptions.h>
00039 #include <utils/common/TplConvert.h>
00040 #include <utils/options/OptionsCont.h>
00041 #include <utils/importio/LineReader.h>
00042 #include <utils/geom/GeoConvHelper.h>
00043 #include <netbuild/NBNetBuilder.h>
00044 #include <netbuild/NBNode.h>
00045 #include <netbuild/NBNodeCont.h>
00046 #include <netbuild/NBEdge.h>
00047 #include <netbuild/NBEdgeCont.h>
00048 #include <netbuild/NBTypeCont.h>
00049 #include <netbuild/NBOwnTLDef.h>
00050 #include <netimport/NINavTeqHelper.h>
00051 #include "NILoader.h"
00052 #include "NIImporter_DlrNavteq.h"
00053 
00054 
00055 #ifdef CHECK_MEMORY_LEAKS
00056 #include <foreign/nvwa/debug_new.h>
00057 #endif // CHECK_MEMORY_LEAKS
00058 
00059 
00060 // ===========================================================================
00061 // method definitions
00062 // ===========================================================================
00063 // ---------------------------------------------------------------------------
00064 // static methods
00065 // ---------------------------------------------------------------------------
00066 void
00067 NIImporter_DlrNavteq::loadNetwork(const OptionsCont& oc, NBNetBuilder& nb) {
00068     // check whether the option is set (properly)
00069     if (!oc.isSet("dlr-navteq-prefix")) {
00070         return;
00071     }
00072     // parse file(s)
00073     LineReader lr;
00074     // load nodes
00075     std::map<std::string, PositionVector> myGeoms;
00076     PROGRESS_BEGIN_MESSAGE("Loading nodes");
00077     std::string file = oc.getString("dlr-navteq-prefix") + "_nodes_unsplitted.txt";
00078     NodesHandler handler1(nb.getNodeCont(), file, myGeoms);
00079     if (!lr.setFile(file)) {
00080         throw ProcessError("The file '" + file + "' could not be opened.");
00081     }
00082     lr.readAll(handler1);
00083     PROGRESS_DONE_MESSAGE();
00084 
00085     // load traffic lights
00086     file = oc.getString("dlr-navteq-prefix") + "_traffic_signals.txt";
00087     if (lr.setFile(file)) {
00088         PROGRESS_BEGIN_MESSAGE("Loading traffic lights");
00089         TrafficlightsHandler handler3(nb.getNodeCont(), nb.getTLLogicCont(), file);
00090         lr.readAll(handler3);
00091         PROGRESS_DONE_MESSAGE();
00092     }
00093 
00094     // load edges
00095     PROGRESS_BEGIN_MESSAGE("Loading edges");
00096     file = oc.getString("dlr-navteq-prefix") + "_links_unsplitted.txt";
00097     // parse the file
00098     EdgesHandler handler2(nb.getNodeCont(), nb.getEdgeCont(), file, myGeoms);
00099     if (!lr.setFile(file)) {
00100         throw ProcessError("The file '" + file + "' could not be opened.");
00101     }
00102     lr.readAll(handler2);
00103     nb.getEdgeCont().recheckLaneSpread();
00104     PROGRESS_DONE_MESSAGE();
00105 }
00106 
00107 
00108 // ---------------------------------------------------------------------------
00109 // definitions of NIImporter_DlrNavteq::NodesHandler-methods
00110 // ---------------------------------------------------------------------------
00111 NIImporter_DlrNavteq::NodesHandler::NodesHandler(NBNodeCont& nc,
00112         const std::string& file,
00113         std::map<std::string, PositionVector> &geoms)
00114     : myNodeCont(nc), myGeoms(geoms) {
00115     UNUSED_PARAMETER(file);
00116 }
00117 
00118 
00119 NIImporter_DlrNavteq::NodesHandler::~NodesHandler() {}
00120 
00121 
00122 bool
00123 NIImporter_DlrNavteq::NodesHandler::report(const std::string& result) {
00124     if (result[0] == '#') {
00125         return true;
00126     }
00127     std::string id;
00128     double x, y;
00129     int no_geoms, intermediate;
00130     // parse
00131     std::istringstream stream(result);
00132     // id
00133     stream >> id;
00134     if (stream.fail()) {
00135         throw ProcessError("Something is wrong with the following data line\n" + result);
00136     }
00137     // intermediate?
00138     stream >> intermediate;
00139     if (stream.fail()) {
00140         if (myNodeCont.size() == 0) { // be generous with extra data at beginning of file
00141             return true;
00142         }
00143         throw ProcessError("Non-numerical value for intermediate status in node " + id + ".");
00144     }
00145     // number of geometrical information
00146     stream >> no_geoms;
00147     if (stream.fail()) {
00148         throw ProcessError("Non-numerical value for number of geometries in node " + id + ".");
00149     }
00150     // geometrical information
00151     PositionVector geoms;
00152     for (int i = 0; i < no_geoms; i++) {
00153         stream >> x;
00154         if (stream.fail()) {
00155             throw ProcessError("Non-numerical value for x-position in node " + id + ".");
00156         }
00157         stream >> y;
00158         if (stream.fail()) {
00159             throw ProcessError("Non-numerical value for y-position in node " + id + ".");
00160         }
00161         Position pos(x, y);
00162         if (!NILoader::transformCoordinates(pos, true)) {
00163             throw ProcessError("Unable to project coordinates for node " + id + ".");
00164         }
00165         geoms.push_back(pos);
00166     }
00167 
00168     if (intermediate == 0) {
00169         NBNode* n = new NBNode(id, geoms[0]);
00170         if (!myNodeCont.insert(n)) {
00171             delete n;
00172             throw ProcessError("Could not add node '" + id + "'.");
00173         }
00174     } else {
00175         myGeoms[id] = geoms;
00176     }
00177     return true;
00178 }
00179 
00180 
00181 // ---------------------------------------------------------------------------
00182 // definitions of NIImporter_DlrNavteq::EdgesHandler-methods
00183 // ---------------------------------------------------------------------------
00184 NIImporter_DlrNavteq::EdgesHandler::EdgesHandler(NBNodeCont& nc, NBEdgeCont& ec,
00185         const std::string& file,
00186         std::map < std::string,
00187         PositionVector > &geoms)
00188     : myNodeCont(nc), myEdgeCont(ec), myGeoms(geoms) {
00189     UNUSED_PARAMETER(file);
00190 }
00191 
00192 
00193 NIImporter_DlrNavteq::EdgesHandler::~EdgesHandler() {}
00194 
00195 
00196 bool
00197 NIImporter_DlrNavteq::EdgesHandler::report(const std::string& result) {
00198 //  0: LINK_ID  NODE_ID_FROM    NODE_ID_TO  BETWEEN_NODE_ID
00199 //  4: length   vehicle_type    form_of_way brunnel_type
00200 //  7: street_type  speed_category  number_of_lanes average_speed
00201 //  10: NAME_ID1    NAME_ID2    housenumbers_right  housenumbers_left
00202 //  ZIP_CODE    AREA_ID SUBAREA_ID  through_traffic special_restrictions
00203 //  extended_number_of_lanes  isRamp    (these two only exist in networks extracted since 05/2009)
00204 //  connection (this may be omitted)
00205 
00206     if (result[0] == '#') {
00207         return true;
00208     }
00209     std::string id, fromID, toID, interID;
00210     SUMOReal length;
00211     SUMOReal speed = (SUMOReal) 30.0 / (SUMOReal) 3.6;
00212     int nolanes = 1;
00213     int priority = -1;
00214     // parse
00215     StringTokenizer st(result, StringTokenizer::WHITECHARS);
00216     // id
00217     id = st.next();
00218     // from node id
00219     fromID = st.next();
00220     // to node id
00221     toID = st.next();
00222     // intermediate node id
00223     interID = st.next();
00224     // length
00225     try {
00226         length = TplConvert<char>::_2SUMOReal(st.next().c_str());
00227     } catch (NumberFormatException&) {
00228         throw ProcessError("Non-numerical value for an edge's length occured (edge '" + id + "'.");
00229     }
00230     // vehicle_type
00231     std::string veh_type = st.next();
00232     // form_of_way
00233     std::string form_of_way = st.next();
00234     // brunnel_type
00235     std::string brunnel_type = st.next();
00236     // street_type
00237     std::string street_type = st.next();
00238     speed = NINavTeqHelper::getSpeed(id, st.next());
00239     // number of lanes
00240     nolanes = NINavTeqHelper::getLaneNumber(id, st.next(), speed);
00241     std::vector<std::string> theRest = st.getVector();
00242     bool connection = (theRest.size() == 11) && (theRest[10] == "1");
00243     if (theRest.size() > 11) {
00244         // post 05/2009 network
00245         if (theRest[11] != "-1") {
00246             try {
00247                 nolanes = TplConvert<char>::_2int(theRest[11].c_str());
00248             } catch (NumberFormatException&) {
00249                 throw ProcessError("Non-numerical value for the extended number of lanes (edge '" + id + "'.");
00250             }
00251         }
00252         connection = (theRest.size() == 13) && (theRest[12] == "1");
00253     }
00254     // try to get the nodes
00255     NBNode* from = myNodeCont.retrieve(fromID);
00256     NBNode* to = myNodeCont.retrieve(toID);
00257     if (from == 0) {
00258         throw ProcessError("The from-node '" + fromID + "' of edge '" + id + "' could not be found");
00259     }
00260     if (to == 0) {
00261         throw ProcessError("The to-node '" + toID + "' of edge '" + id + "' could not be found");
00262     }
00263     // build the edge
00264     NBEdge* e = 0;
00265     if (interID == "-1") {
00266         e = new NBEdge(id, from, to, "", speed, nolanes, priority, -1, -1);
00267     } else {
00268         PositionVector geoms = myGeoms[interID];
00269         if (connection) {
00270             geoms = geoms.reverse();
00271             geoms.push_front(from->getPosition());
00272             geoms.push_back(to->getPosition());
00273             e = new NBEdge(id, from, to, "", speed, nolanes, priority, -1, -1, geoms, "", LANESPREAD_CENTER);
00274         } else {
00275             geoms.push_front(from->getPosition());
00276             geoms.push_back(to->getPosition());
00277             e = new NBEdge(id, from, to, "", speed, nolanes, priority, -1, -1, geoms, "", LANESPREAD_CENTER);
00278         }
00279     }
00280     // add vehicle type information to the edge
00281     NINavTeqHelper::addVehicleClasses(*e, veh_type);
00282     // insert the edge to the network
00283     if (!myEdgeCont.insert(e)) {
00284         delete e;
00285         throw ProcessError("Could not add edge '" + id + "'.");
00286     }
00287     return true;
00288 }
00289 
00290 
00291 // ---------------------------------------------------------------------------
00292 // definitions of NIImporter_DlrNavteq::TrafficlightsHandler-methods
00293 // ---------------------------------------------------------------------------
00294 NIImporter_DlrNavteq::TrafficlightsHandler::TrafficlightsHandler(NBNodeCont& nc,
00295         NBTrafficLightLogicCont& tlc,
00296         const std::string& file)
00297     : myNodeCont(nc), myTLLogicCont(tlc) {
00298     UNUSED_PARAMETER(file);
00299 }
00300 
00301 
00302 NIImporter_DlrNavteq::TrafficlightsHandler::~TrafficlightsHandler() {}
00303 
00304 
00305 bool
00306 NIImporter_DlrNavteq::TrafficlightsHandler::report(const std::string& result) {
00307 // #ID     POICOL-TYPE     DESCRIPTION     LONGITUDE       LATITUDE        NAVTEQ_LINK_ID  NODEID
00308 
00309     if (result[0] == '#') {
00310         return true;
00311     }
00312     StringTokenizer st(result, StringTokenizer::WHITECHARS);
00313     std::string nodeID = st.getVector().back();
00314     NBNode* node = myNodeCont.retrieve(nodeID);
00315     if (node == 0) {
00316         WRITE_WARNING("The traffic light node '" + nodeID + "' could not be found");
00317     } else {
00318         if (node->getType() != NODETYPE_TRAFFIC_LIGHT) {
00319             node->reinit(node->getPosition(), NODETYPE_TRAFFIC_LIGHT);
00320             NBTrafficLightDefinition* tlDef = new NBOwnTLDef(nodeID, node);
00321             if (!myTLLogicCont.insert(tlDef)) {
00322                 // actually, nothing should fail here
00323                 delete tlDef;
00324                 throw ProcessError("Could not allocate tls for '" + nodeID + "'.");
00325             }
00326         }
00327     }
00328     return true;
00329 }
00330 
00331 /****************************************************************************/
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Friends Defines