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