SUMO - Simulation of Urban MObility
NIXMLNodesHandler.cpp
Go to the documentation of this file.
00001 /****************************************************************************/
00010 // Importer for network nodes stored in XML
00011 /****************************************************************************/
00012 // SUMO, Simulation of Urban MObility; see http://sumo.sourceforge.net/
00013 // Copyright (C) 2001-2012 DLR (http://www.dlr.de/) and contributors
00014 /****************************************************************************/
00015 //
00016 //   This file is part of SUMO.
00017 //   SUMO is free software: you can redistribute it and/or modify
00018 //   it under the terms of the GNU General Public License as published by
00019 //   the Free Software Foundation, either version 3 of the License, or
00020 //   (at your option) any later version.
00021 //
00022 /****************************************************************************/
00023 
00024 
00025 // ===========================================================================
00026 // included modules
00027 // ===========================================================================
00028 #ifdef _MSC_VER
00029 #include <windows_config.h>
00030 #else
00031 #include <config.h>
00032 #endif
00033 
00034 #include <string>
00035 #include <iostream>
00036 #include <xercesc/sax/HandlerBase.hpp>
00037 #include <xercesc/sax/AttributeList.hpp>
00038 #include <xercesc/sax/SAXParseException.hpp>
00039 #include <xercesc/sax/SAXException.hpp>
00040 #include <utils/xml/SUMOSAXHandler.h>
00041 #include <utils/xml/SUMOXMLDefinitions.h>
00042 #include <utils/common/MsgHandler.h>
00043 #include <utils/common/TplConvert.h>
00044 #include <utils/common/ToString.h>
00045 #include <utils/common/StringTokenizer.h>
00046 #include <utils/options/OptionsCont.h>
00047 #include <utils/geom/GeoConvHelper.h>
00048 #include <netbuild/NBNodeCont.h>
00049 #include <netbuild/NBTrafficLightLogicCont.h>
00050 #include <netbuild/NBOwnTLDef.h>
00051 #include "NILoader.h"
00052 #include "NIXMLNodesHandler.h"
00053 #include "NIImporter_SUMO.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 NIXMLNodesHandler::NIXMLNodesHandler(NBNodeCont& nc,
00064                                      NBTrafficLightLogicCont& tlc,
00065                                      OptionsCont& options) : 
00066     SUMOSAXHandler("xml-nodes - file"),
00067     myOptions(options),
00068     myNodeCont(nc), 
00069     myTLLogicCont(tlc),
00070     myLocation(0) 
00071 {}
00072 
00073 
00074 NIXMLNodesHandler::~NIXMLNodesHandler() {
00075     delete myLocation;
00076 }
00077 
00078 
00079 void
00080 NIXMLNodesHandler::myStartElement(int element,
00081                                   const SUMOSAXAttributes& attrs) {
00082     switch (element) {
00083         case SUMO_TAG_LOCATION:
00084             myLocation = NIImporter_SUMO::loadLocation(attrs);
00085             break;
00086         case SUMO_TAG_NODE:
00087             addNode(attrs);
00088             break;
00089         case SUMO_TAG_JOIN:
00090             addJoinCluster(attrs);
00091             break;
00092         case SUMO_TAG_JOINEXCLUDE:
00093             addJoinExclusion(attrs);
00094             break;
00095         case SUMO_TAG_DELETE:
00096             deleteNode(attrs);
00097             break;
00098         default:
00099             break;
00100     }
00101 }
00102 
00103 
00104 void
00105 NIXMLNodesHandler::addNode(const SUMOSAXAttributes& attrs) {
00106     bool ok = true;
00107     // get the id, report a warning if not given or empty...
00108     myID = attrs.getStringReporting(SUMO_ATTR_ID, 0, ok);
00109     if (!ok) {
00110         return;
00111     }
00112     NBNode* node = myNodeCont.retrieve(myID);
00113     // retrieve the position of the node
00114     bool xOk = false;
00115     bool yOk = false;
00116     bool needConversion = true;
00117     if (node != 0) {
00118         myPosition = node->getPosition();
00119         xOk = yOk = true;
00120         needConversion = false;
00121     }
00122     if (attrs.hasAttribute(SUMO_ATTR_X)) {
00123         myPosition.set(attrs.getSUMORealReporting(SUMO_ATTR_X, myID.c_str(), ok), myPosition.y());
00124         xOk = true;
00125         needConversion = true;
00126     }
00127     if (attrs.hasAttribute(SUMO_ATTR_Y)) {
00128         myPosition.set(myPosition.x(), attrs.getSUMORealReporting(SUMO_ATTR_Y, myID.c_str(), ok));
00129         yOk = true;
00130         needConversion = true;
00131     }
00132     if (attrs.hasAttribute(SUMO_ATTR_Z)) {
00133         myPosition.set(myPosition.x(), myPosition.y(), attrs.getSUMORealReporting(SUMO_ATTR_Z, myID.c_str(), ok));
00134     }
00135     if (xOk && yOk) {
00136         if (needConversion && !NILoader::transformCoordinates(myPosition, true, myLocation)) {
00137             WRITE_ERROR("Unable to project coordinates for node '" + myID + "'.");
00138         }
00139     } else {
00140         WRITE_ERROR("Missing position (at node ID='" + myID + "').");
00141     }
00142     bool updateEdgeGeometries = node != 0 && myPosition != node->getPosition();
00143     // check whether the y-axis shall be flipped
00144     if (myOptions.getBool("flip-y-axis")) {
00145         myPosition.mul(1.0, -1.0);
00146     }
00147     // get the type
00148     SumoXMLNodeType type = NODETYPE_UNKNOWN;
00149     if (node != 0) {
00150         type = node->getType();
00151     }
00152     std::string typeS = attrs.getOptStringReporting(SUMO_ATTR_TYPE, myID.c_str(), ok, "");
00153     if (SUMOXMLDefinitions::NodeTypes.hasString(typeS)) {
00154         type = SUMOXMLDefinitions::NodeTypes.get(typeS);
00155     }
00156 
00157     // check whether a prior node shall be modified
00158     if (node == 0) {
00159         node = new NBNode(myID, myPosition, type);
00160         if (!myNodeCont.insert(node)) {
00161             throw ProcessError("Could not insert node though checked this before (id='" + myID + "').");
00162         }
00163     } else {
00164         // remove previously set tls if this node is not controlled by a tls
00165         std::set<NBTrafficLightDefinition*> tls = node->getControllingTLS();
00166         node->removeTrafficLights();
00167         for (std::set<NBTrafficLightDefinition*>::iterator i = tls.begin(); i != tls.end(); ++i) {
00168             if ((*i)->getNodes().size() == 0) {
00169                 myTLLogicCont.removeFully((*i)->getID());
00170             }
00171         }
00172         // patch information
00173         node->reinit(myPosition, type, updateEdgeGeometries);
00174     }
00175     // process traffic light definition
00176     if (type == NODETYPE_TRAFFIC_LIGHT) {
00177         processTrafficLightDefinitions(attrs, node);
00178     }
00179 }
00180 
00181 
00182 void
00183 NIXMLNodesHandler::deleteNode(const SUMOSAXAttributes& attrs) {
00184     bool ok = true;
00185     // get the id, report a warning if not given or empty...
00186     myID = attrs.getStringReporting(SUMO_ATTR_ID, 0, ok);
00187     if (!ok) {
00188         return;
00189     }
00190     NBNode* node = myNodeCont.retrieve(myID);
00191     if (node == 0) {
00192         WRITE_WARNING("Ignoring tag '" + toString(SUMO_TAG_DELETE) + "' for unknown node '" +
00193                       myID + "'");
00194         return;
00195     } else {
00196         myNodeCont.extract(node, true);
00197     }
00198 }
00199 
00200 
00201 void
00202 NIXMLNodesHandler::addJoinCluster(const SUMOSAXAttributes& attrs) {
00203     bool ok = true;
00204     const std::string clusterString = attrs.getStringReporting(SUMO_ATTR_NODES, 0, ok);
00205     const std::vector<std::string> ids = StringTokenizer(clusterString).getVector();
00206     if (ok) {
00207         myNodeCont.addCluster2Join(std::set<std::string>(ids.begin(), ids.end()));
00208     }
00209 }
00210 
00211 
00212 void
00213 NIXMLNodesHandler::addJoinExclusion(const SUMOSAXAttributes& attrs) {
00214     bool ok = true;
00215     const std::vector<std::string> ids = StringTokenizer(
00216             attrs.getStringReporting(SUMO_ATTR_NODES, 0, ok)).getVector();
00217     if (ok) {
00218         myNodeCont.addJoinExclusion(ids);
00219     }
00220 }
00221 
00222 
00223 void
00224 NIXMLNodesHandler::processTrafficLightDefinitions(const SUMOSAXAttributes& attrs,
00225         NBNode* currentNode) {
00226     // try to get the tl-id
00227     // if a tl-id is given, we will look whether this tl already exists
00228     //  if so, we will add the node to it (and to all programs with this id), otherwise allocate a new one with this id
00229     // if no tl-id exists, we will build a tl with the node's id
00230     std::set<NBTrafficLightDefinition*> tlDefs;
00231     bool ok = true;
00232     std::string tlID = attrs.getOptStringReporting(SUMO_ATTR_TLID, 0, ok, "");
00233     if (tlID != "" && myTLLogicCont.getPrograms(tlID).size() > 0) {
00234         // we already have definitions for this tlID
00235         const std::map<std::string, NBTrafficLightDefinition*>& programs = myTLLogicCont.getPrograms(tlID);
00236         std::map<std::string, NBTrafficLightDefinition*>::const_iterator it;
00237         for (it = programs.begin(); it != programs.end(); it++) {
00238             tlDefs.insert(it->second);
00239             it->second->addNode(currentNode);
00240         }
00241     } else {
00242         // we need to add a new defition
00243         tlID = tlID == "" ? myID : tlID;
00244         NBTrafficLightDefinition* tlDef = new NBOwnTLDef(tlID, currentNode);
00245         if (!myTLLogicCont.insert(tlDef)) {
00246             // actually, nothing should fail here
00247             delete tlDef;
00248             throw ProcessError("Could not allocate tls '" + myID + "'.");
00249         }
00250         tlDefs.insert(tlDef);
00251     }
00252     // process inner edges which shall be controlled
00253     std::vector<std::string> controlledInner;
00254     if (attrs.hasAttribute(SUMO_ATTR_CONTROLLED_INNER__DEPRECATED)) {
00255         SUMOSAXAttributes::parseStringVector(attrs.getStringReporting(SUMO_ATTR_CONTROLLED_INNER__DEPRECATED, 0, ok), controlledInner);
00256     } else {
00257         SUMOSAXAttributes::parseStringVector(attrs.getOptStringReporting(SUMO_ATTR_CONTROLLED_INNER, 0, ok, ""), controlledInner);
00258     }
00259     if (controlledInner.size() != 0) {
00260         for (std::set<NBTrafficLightDefinition*>::iterator it = tlDefs.begin(); it != tlDefs.end(); it++) {
00261             (*it)->addControlledInnerEdges(controlledInner);
00262         }
00263     }
00264 }
00265 
00266 
00267 
00268 /****************************************************************************/
00269 
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Friends Defines