SUMO - Simulation of Urban MObility

NIXMLTrafficLightsHandler.cpp

Go to the documentation of this file.
00001 /****************************************************************************/
00007 // Importer for traffic lights stored in XML
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 <iostream>
00032 #include <xercesc/sax/HandlerBase.hpp>
00033 #include <xercesc/sax/AttributeList.hpp>
00034 #include <xercesc/sax/SAXParseException.hpp>
00035 #include <xercesc/sax/SAXException.hpp>
00036 #include <utils/common/StringTokenizer.h>
00037 #include <utils/xml/SUMOSAXHandler.h>
00038 #include <utils/xml/SUMOXMLDefinitions.h>
00039 #include <utils/common/ToString.h>
00040 #include <utils/common/TplConvert.h>
00041 #include <utils/common/TplConvertSec.h>
00042 #include <utils/common/UtilExceptions.h>
00043 #include <utils/common/MsgHandler.h>
00044 #include <utils/options/OptionsCont.h>
00045 #include <netbuild/NBEdge.h>
00046 #include <netbuild/NBEdgeCont.h>
00047 #include <netbuild/NBNode.h>
00048 #include <netbuild/NBOwnTLDef.h>
00049 #include <netbuild/NBLoadedSUMOTLDef.h>
00050 #include <netbuild/NBTrafficLightLogicCont.h>
00051 #include "NIImporter_SUMO.h"
00052 #include "NIXMLTrafficLightsHandler.h"
00053 
00054 #ifdef CHECK_MEMORY_LEAKS
00055 #include <foreign/nvwa/debug_new.h>
00056 #endif // CHECK_MEMORY_LEAKS
00057 
00058 
00059 // ===========================================================================
00060 // method definitions
00061 // ===========================================================================
00062 NIXMLTrafficLightsHandler::NIXMLTrafficLightsHandler(
00063     NBTrafficLightLogicCont& tlCont, NBEdgeCont& ec) throw() :
00064     SUMOSAXHandler("xml-tllogics"),
00065     myTLLCont(tlCont),
00066     myEdgeCont(ec),
00067     myCurrentTL(0),
00068     myResetPhases(false)
00069 {}
00070 
00071 
00072 NIXMLTrafficLightsHandler::~NIXMLTrafficLightsHandler() throw() {}
00073 
00074 
00075 void
00076 NIXMLTrafficLightsHandler::myStartElement(
00077     int element, const SUMOSAXAttributes& attrs) throw(ProcessError) {
00078     switch (element) {
00079     case SUMO_TAG_TLLOGIC:
00080         myCurrentTL = initTrafficLightLogic(attrs, myCurrentTL);
00081         break;
00082     case SUMO_TAG_PHASE:
00083         if (myResetPhases) {
00084             myCurrentTL->getLogic()->resetPhases();
00085             myResetPhases = false;
00086         }
00087         NIImporter_SUMO::addPhase(attrs, myCurrentTL);
00088         break;
00089     case SUMO_TAG_CONNECTION:
00090         addTlConnection(attrs);
00091         break;
00092     case SUMO_TAG_RESET:
00093         removeTlConnection(attrs);
00094         break;
00095     default:
00096         break;
00097     }
00098 }
00099 
00100 
00101 void
00102 NIXMLTrafficLightsHandler::myEndElement(int element) throw(ProcessError) {
00103     switch (element) {
00104     case SUMO_TAG_TLLOGIC:
00105         if (!myCurrentTL) {
00106             WRITE_ERROR("Unmatched closing tag for tl-logic.");
00107         } else {
00108             if (!myTLLCont.insert(myCurrentTL)) {
00109                 WRITE_MESSAGE("Updating program '" + myCurrentTL->getProgramID() +
00110                               "' for traffic light '" + myCurrentTL->getID() + "'");
00111             }
00112             myCurrentTL = 0;
00113         }
00114         break;
00115     default:
00116         break;
00117     }
00118 }
00119 
00120 
00121 NBLoadedSUMOTLDef*
00122 NIXMLTrafficLightsHandler::initTrafficLightLogic(const SUMOSAXAttributes& attrs, NBLoadedSUMOTLDef* currentTL) {
00123     if (currentTL) {
00124         WRITE_ERROR("Definition of tl-logic '" + currentTL->getID() + "' was not finished.");
00125         return 0;
00126     }
00127     bool ok = true;
00128     std::string id = attrs.getStringReporting(SUMO_ATTR_ID, 0, ok);
00129     std::string programID = attrs.getOptStringReporting(SUMO_ATTR_PROGRAMID, id.c_str(), ok, "<unknown>");
00130 
00131     // there are two scenarios to consider
00132     // 1) the tll.xml is loaded to updated traffic lights defined in a net.xml:
00133     //   simply retrieve the loaded definitions and update them
00134     // 2) the tll.xml is loaded to define new traffic lights
00135     //   nod.xml will have triggered building of NBOwnTLDef. Replace it with NBLoadedSUMOTLDef
00136     NBLoadedSUMOTLDef* loadedDef = dynamic_cast<NBLoadedSUMOTLDef*>(myTLLCont.getDefinition(id, programID));
00137     if (loadedDef == 0) {
00138         // case 2
00139         NBOwnTLDef* newDef = dynamic_cast<NBOwnTLDef*>(myTLLCont.getDefinition(
00140                                  id, NBTrafficLightDefinition::DefaultProgramID));
00141         assert(newDef != 0);
00142         loadedDef = new NBLoadedSUMOTLDef(id, programID, 0);
00143         std::vector<NBNode*> nodes = newDef->getControlledNodes();
00144         for (std::vector<NBNode*>::iterator it=nodes.begin(); it != nodes.end(); it++) {
00145             (*it)->removeTrafficLight(newDef);
00146             (*it)->addTrafficLight(loadedDef);
00147         }
00148         myTLLCont.removeProgram(id, NBTrafficLightDefinition::DefaultProgramID);
00149         myTLLCont.insert(loadedDef);
00150 
00151         std::string type = attrs.getOptStringReporting(SUMO_ATTR_TYPE, 0, ok, toString(TLTYPE_STATIC));
00152         if (type != toString(TLTYPE_STATIC)) {
00153             WRITE_WARNING("Traffic light '" + id + "' has unsupported type '" + type + "' and will be converted to '" +
00154                           toString(TLTYPE_STATIC) + "'");
00155         }
00156     }
00157     if (attrs.hasAttribute(SUMO_ATTR_OFFSET)) {
00158         SUMOTime offset = TIME2STEPS(attrs.getSUMORealReporting(SUMO_ATTR_OFFSET, id.c_str(), ok));
00159         loadedDef->getLogic()->setOffset(offset);
00160     }
00161     if (ok) {
00162         myResetPhases = true;
00163         return loadedDef;
00164     } else {
00165         return 0;
00166     }
00167 }
00168 
00169 
00170 void
00171 NIXMLTrafficLightsHandler::addTlConnection(const SUMOSAXAttributes& attrs) {
00172     bool ok = true;
00173     // parse identifying attributes
00174     NBEdge* from = retrieveEdge(attrs, SUMO_ATTR_FROM, ok);
00175     NBEdge* to = retrieveEdge(attrs, SUMO_ATTR_TO, ok);
00176     if (!ok) {
00177         return;
00178     }
00179     int fromLane = retrieveLaneIndex(attrs, SUMO_ATTR_FROM_LANE, from, ok);
00180     int toLane = retrieveLaneIndex(attrs, SUMO_ATTR_TO_LANE, to, ok);
00181     if (!ok) {
00182         return;
00183     }
00184     // retrieve connection
00185     const std::vector<NBEdge::Connection> &connections = from->getConnections();
00186     std::vector<NBEdge::Connection>::const_iterator con_it;
00187     con_it = find_if(connections.begin(), connections.end(),
00188                      NBEdge::connections_finder(fromLane, to, toLane));
00189     if (con_it == connections.end()) {
00190         WRITE_ERROR("Connection from=" + from->getID() + " to=" + to->getID() +
00191                     " fromLane=" + toString(fromLane) + " toLane=" + toString(toLane) + " not found");
00192         return;
00193     }
00194     NBEdge::Connection c = *con_it;
00195     // read other  attributes
00196     std::string tlID = attrs.getOptStringReporting(SUMO_ATTR_TLID, 0, ok, "");
00197     if (tlID == "") {
00198         // we are updating an existing connection
00199         tlID = c.tlID;
00200         assert(tlID != "");
00201     }
00202     int tlIndex = attrs.getOptIntReporting(SUMO_ATTR_TLLINKINDEX, 0, ok, -1);
00203     if (tlIndex == -1) {
00204         // we are updating an existing connection
00205         tlIndex = c.tlLinkNo;
00206     }
00207 
00208     // register the connection with all definitions
00209     const std::map<std::string, NBTrafficLightDefinition*>& programs = myTLLCont.getPrograms(tlID);
00210     if (programs.size() > 0) {
00211         std::map<std::string, NBTrafficLightDefinition*>::const_iterator it;
00212         for (it = programs.begin(); it!= programs.end(); it++) {
00213             NBLoadedSUMOTLDef* tlDef = dynamic_cast<NBLoadedSUMOTLDef*>(it->second);
00214             if (tlDef) {
00215                 tlDef->addConnection(from, c.toEdge, c.fromLane, c.toLane, tlIndex);
00216             } else {
00217                 throw ProcessError("Corrupt traffic light definition '"
00218                                    + tlID + "' (program '" + it->first + "')");
00219             }
00220         }
00221     } else {
00222         WRITE_ERROR("The traffic light '" + tlID + "' is not known.");
00223     }
00224 }
00225 
00226 
00227 void
00228 NIXMLTrafficLightsHandler::removeTlConnection(const SUMOSAXAttributes& attrs) {
00229     bool ok = true;
00230     std::string tlID = attrs.getStringReporting(SUMO_ATTR_TLID, 0, ok);
00231     // does the traffic light still exist?
00232     const std::map<std::string, NBTrafficLightDefinition*>& programs = myTLLCont.getPrograms(tlID);
00233     if (programs.size() > 0) {
00234         // parse identifying attributes
00235         NBEdge* from = retrieveEdge(attrs, SUMO_ATTR_FROM, ok);
00236         NBEdge* to = retrieveEdge(attrs, SUMO_ATTR_TO, ok);
00237         if (!ok) {
00238             return;
00239         }
00240         int fromLane = retrieveLaneIndex(attrs, SUMO_ATTR_FROM_LANE, from, ok);
00241         int toLane = retrieveLaneIndex(attrs, SUMO_ATTR_TO_LANE, to, ok);
00242         if (!ok) {
00243             return;
00244         }
00245         int tlIndex = attrs.getIntReporting(SUMO_ATTR_TLLINKINDEX, 0, ok);
00246 
00247         NBConnection conn(from, fromLane, to, toLane, tlIndex);
00248         // remove the connection from all definitions
00249         std::map<std::string, NBTrafficLightDefinition*>::const_iterator it;
00250         for (it = programs.begin(); it!= programs.end(); it++) {
00251             NBLoadedSUMOTLDef* tlDef = dynamic_cast<NBLoadedSUMOTLDef*>(it->second);
00252             if (tlDef) {
00253                 tlDef->removeConnection(conn, false);
00254             } else {
00255                 throw ProcessError("Corrupt traffic light definition '"
00256                                    + tlID + "' (program '" + it->first + "')");
00257             }
00258         }
00259     }
00260 }
00261 
00262 
00263 NBEdge*
00264 NIXMLTrafficLightsHandler::retrieveEdge(
00265     const SUMOSAXAttributes& attrs, SumoXMLAttr attr, bool& ok) {
00266     std::string edgeID = attrs.getStringReporting(attr, 0, ok);
00267     NBEdge* edge = myEdgeCont.retrieve(edgeID, true);
00268     if (edge == 0) {
00269         WRITE_ERROR("Unknown edge '" + edgeID + "' given in connection.");
00270         ok = false;
00271     }
00272     return edge;
00273 }
00274 
00275 
00276 int
00277 NIXMLTrafficLightsHandler::retrieveLaneIndex(
00278     const SUMOSAXAttributes& attrs, SumoXMLAttr attr, NBEdge* edge, bool& ok) {
00279     int laneIndex = attrs.getIntReporting(attr, 0, ok);
00280     if (edge->getNumLanes()<=(size_t) laneIndex) {
00281         WRITE_ERROR("Invalid lane index '" + toString(laneIndex) + "' for edge '" + edge->getID() + "'.");
00282         ok = false;
00283     }
00284     return laneIndex;
00285 }
00286 
00287 
00288 /****************************************************************************/
00289 
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Friends Defines