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