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