SUMO - Simulation of Urban MObility

NIXMLNodesHandler.cpp

Go to the documentation of this file.
00001 /****************************************************************************/
00007 // Importer for network nodes 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/xml/SUMOSAXHandler.h>
00037 #include <utils/xml/SUMOXMLDefinitions.h>
00038 #include <utils/common/MsgHandler.h>
00039 #include <utils/common/TplConvert.h>
00040 #include <utils/common/ToString.h>
00041 #include <utils/common/StringTokenizer.h>
00042 #include <utils/options/OptionsCont.h>
00043 #include <utils/geom/GeoConvHelper.h>
00044 #include <netbuild/NBNodeCont.h>
00045 #include <netbuild/NBTrafficLightLogicCont.h>
00046 #include <netbuild/NBOwnTLDef.h>
00047 #include "NILoader.h"
00048 #include "NIXMLNodesHandler.h"
00049 
00050 #ifdef CHECK_MEMORY_LEAKS
00051 #include <foreign/nvwa/debug_new.h>
00052 #endif // CHECK_MEMORY_LEAKS
00053 
00054 
00055 // ===========================================================================
00056 // method definitions
00057 // ===========================================================================
00058 NIXMLNodesHandler::NIXMLNodesHandler(NBNodeCont& nc,
00059                                      NBTrafficLightLogicCont& tlc,
00060                                      OptionsCont& options)
00061     : SUMOSAXHandler("xml-nodes - file"),
00062       myOptions(options),
00063       myNodeCont(nc), myTLLogicCont(tlc) {}
00064 
00065 
00066 NIXMLNodesHandler::~NIXMLNodesHandler() throw() {}
00067 
00068 
00069 void
00070 NIXMLNodesHandler::myStartElement(int element,
00071                                   const SUMOSAXAttributes& attrs) throw(ProcessError) {
00072     switch (element) {
00073     case SUMO_TAG_NODE:
00074         addNode(attrs);
00075         break;
00076     case SUMO_TAG_JOIN:
00077         addJoinCluster(attrs);
00078         break;
00079     case SUMO_TAG_JOINEXCLUDE:
00080         addJoinExclusion(attrs);
00081         break;
00082     case SUMO_TAG_RESET:
00083         deleteNode(attrs);
00084         break;
00085     default:
00086         break;
00087     }
00088 }
00089 
00090 
00091 void
00092 NIXMLNodesHandler::addNode(const SUMOSAXAttributes& attrs) {
00093     bool ok = true;
00094     // get the id, report a warning if not given or empty...
00095     myID = attrs.getStringReporting(SUMO_ATTR_ID, 0, ok);
00096     if (!ok) {
00097         return;
00098     }
00099     NBNode* node = myNodeCont.retrieve(myID);
00100     // retrieve the position of the node
00101     bool xOk = false;
00102     bool yOk = false;
00103     bool needConversion = true;
00104     if (node!=0) {
00105         myPosition = node->getPosition();
00106         xOk = yOk = true;
00107         needConversion = false;
00108     }
00109     if (attrs.hasAttribute(SUMO_ATTR_X)) {
00110         myPosition.set(attrs.getSUMORealReporting(SUMO_ATTR_X, myID.c_str(), ok), myPosition.y());
00111         xOk = true;
00112         needConversion = true;
00113     }
00114     if (attrs.hasAttribute(SUMO_ATTR_Y)) {
00115         myPosition.set(myPosition.x(), attrs.getSUMORealReporting(SUMO_ATTR_Y, myID.c_str(), ok));
00116         yOk = true;
00117         needConversion = true;
00118     }
00119     if (attrs.hasAttribute(SUMO_ATTR_Z)) {
00120         myPosition.set(myPosition.x(), myPosition.y(), attrs.getSUMORealReporting(SUMO_ATTR_Z, myID.c_str(), ok));
00121     }
00122     if (xOk&&yOk) {
00123         if (needConversion&&!NILoader::transformCoordinates(myPosition)) {
00124             WRITE_ERROR("Unable to project coordinates for node '" + myID + "'.");
00125         }
00126     } else {
00127         WRITE_ERROR("Missing position (at node ID='" + myID + "').");
00128     }
00129     bool updateEdgeGeometries = node!=0 && myPosition != node->getPosition();
00130     // check whether the y-axis shall be flipped
00131     if (myOptions.getBool("flip-y-axis")) {
00132         myPosition.mul(1.0, -1.0);
00133     }
00134     // get the type
00135     SumoXMLNodeType type = NODETYPE_UNKNOWN;
00136     if (node!=0) {
00137         type = node->getType();
00138     }
00139     std::string typeS = attrs.getOptStringReporting(SUMO_ATTR_TYPE, myID.c_str(), ok, "");
00140     if (SUMOXMLDefinitions::NodeTypes.hasString(typeS)) {
00141         type = SUMOXMLDefinitions::NodeTypes.get(typeS);
00142     }
00143 
00144     // check whether a prior node shall be modified
00145     if (node==0) {
00146         node = new NBNode(myID, myPosition, type);
00147         if (!myNodeCont.insert(node)) {
00148             throw ProcessError("Could not insert node though checked this before (id='" + myID + "').");
00149         }
00150     } else {
00151         // remove previously set tls if this node is not controlled by a tls
00152         std::set<NBTrafficLightDefinition*> tls = node->getControllingTLS();
00153         node->removeTrafficLights();
00154         for (std::set<NBTrafficLightDefinition*>::iterator i=tls.begin(); i!=tls.end(); ++i) {
00155             if ((*i)->getNodes().size()==0) {
00156                 myTLLogicCont.removeFully((*i)->getID());
00157             }
00158         }
00159         // patch information
00160         node->reinit(myPosition, type, updateEdgeGeometries);
00161     }
00162     // process traffic light definition
00163     if (type==NODETYPE_TRAFFIC_LIGHT) {
00164         processTrafficLightDefinitions(attrs, node);
00165     }
00166 }
00167 
00168 
00169 void
00170 NIXMLNodesHandler::deleteNode(const SUMOSAXAttributes& attrs) {
00171     bool ok = true;
00172     // get the id, report a warning if not given or empty...
00173     myID = attrs.getStringReporting(SUMO_ATTR_ID, 0, ok);
00174     if (!ok) {
00175         return;
00176     }
00177     NBNode* node = myNodeCont.retrieve(myID);
00178     if (node == 0) {
00179         WRITE_WARNING("Ignoring tag '" + toString(SUMO_TAG_RESET) + "' for unknown node '" +
00180                       myID + "'");
00181         return;
00182     } else {
00183         myNodeCont.extract(node, true);
00184     }
00185 }
00186 
00187 
00188 void
00189 NIXMLNodesHandler::addJoinCluster(const SUMOSAXAttributes& attrs) {
00190     bool ok = true;
00191     const std::string clusterString = attrs.getStringReporting(SUMO_ATTR_NODES, 0, ok);
00192     const std::vector<std::string> ids = StringTokenizer(clusterString).getVector();
00193     if (ok) {
00194         myNodeCont.addCluster2Join(std::set<std::string>(ids.begin(), ids.end()));
00195     }
00196 }
00197 
00198 
00199 void
00200 NIXMLNodesHandler::addJoinExclusion(const SUMOSAXAttributes& attrs) {
00201     bool ok = true;
00202     const std::vector<std::string> ids = StringTokenizer(
00203             attrs.getStringReporting(SUMO_ATTR_NODES, 0, ok)).getVector();
00204     if (ok) {
00205         myNodeCont.addJoinExclusion(ids);
00206     }
00207 }
00208 
00209 
00210 void
00211 NIXMLNodesHandler::processTrafficLightDefinitions(const SUMOSAXAttributes& attrs,
00212         NBNode* currentNode) {
00213     // try to get the tl-id
00214     // if a tl-id is given, we will look whether this tl already exists
00215     //  if so, we will add the node to it (and to all programs with this id), otherwise allocate a new one with this id
00216     // if no tl-id exists, we will build a tl with the node's id
00217     std::set<NBTrafficLightDefinition*> tlDefs;
00218     bool ok = true;
00219     std::string tlID = attrs.getOptStringReporting(SUMO_ATTR_TLID, 0, ok, "");
00220     if (tlID!="" && myTLLogicCont.getPrograms(tlID).size() > 0) {
00221         // we already have definitions for this tlID
00222         const std::map<std::string, NBTrafficLightDefinition*>& programs = myTLLogicCont.getPrograms(tlID);
00223         std::map<std::string, NBTrafficLightDefinition*>::const_iterator it;
00224         for (it = programs.begin(); it!= programs.end(); it++) {
00225             tlDefs.insert(it->second);
00226             it->second->addNode(currentNode);
00227         }
00228     } else {
00229         // we need to add a new defition
00230         tlID = tlID == "" ? myID : tlID;
00231         NBTrafficLightDefinition* tlDef = new NBOwnTLDef(tlID, currentNode);
00232         if (!myTLLogicCont.insert(tlDef)) {
00233             // actually, nothing should fail here
00234             delete tlDef;
00235             throw ProcessError("Could not allocate tls '" + myID + "'.");
00236         }
00237         tlDefs.insert(tlDef);
00238     }
00239     // process inner edges which shall be controlled
00240     std::vector<std::string> controlledInner;
00241     if (attrs.hasAttribute(SUMO_ATTR_CONTROLLED_INNER__DEPRECATED)) {
00242         SUMOSAXAttributes::parseStringVector(attrs.getStringReporting(SUMO_ATTR_CONTROLLED_INNER__DEPRECATED, 0, ok), controlledInner);
00243     } else {
00244         SUMOSAXAttributes::parseStringVector(attrs.getOptStringReporting(SUMO_ATTR_CONTROLLED_INNER, 0, ok, ""), controlledInner);
00245     }
00246     if (controlledInner.size()!=0) {
00247         for (std::set<NBTrafficLightDefinition*>::iterator it = tlDefs.begin(); it!= tlDefs.end(); it++) {
00248             (*it)->addControlledInnerEdges(controlledInner);
00249         }
00250     }
00251 }
00252 
00253 
00254 
00255 /****************************************************************************/
00256 
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Friends Defines