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