00001
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #ifdef _MSC_VER
00025 #include <windows_config.h>
00026 #else
00027 #include <config.h>
00028 #endif
00029
00030 #include <string>
00031 #include <utils/options/OptionsCont.h>
00032 #include <utils/common/MsgHandler.h>
00033 #include <utils/common/StringTokenizer.h>
00034 #include <utils/common/UtilExceptions.h>
00035 #include <utils/xml/SUMOSAXHandler.h>
00036 #include <utils/xml/SUMOXMLDefinitions.h>
00037 #include "ROEdge.h"
00038 #include "ROLane.h"
00039 #include "RONode.h"
00040 #include "RONet.h"
00041 #include "RONetHandler.h"
00042 #include "ROAbstractEdgeBuilder.h"
00043
00044 #ifdef CHECK_MEMORY_LEAKS
00045 #include <foreign/nvwa/debug_new.h>
00046 #endif // CHECK_MEMORY_LEAKS
00047
00048
00049
00050
00051
00052 RONetHandler::RONetHandler(RONet &net,
00053 ROAbstractEdgeBuilder &eb)
00054 : SUMOSAXHandler("sumo-network"),
00055 myNet(net), myCurrentName(),
00056 myCurrentEdge(0), myEdgeBuilder(eb), myHaveWarnedAboutDeprecatedVClass(false) {}
00057
00058
00059 RONetHandler::~RONetHandler() throw() {}
00060
00061
00062 void
00063 RONetHandler::myStartElement(SumoXMLTag element,
00064 const SUMOSAXAttributes &attrs) throw(ProcessError) {
00065 switch (element) {
00066 case SUMO_TAG_EDGE:
00067
00068
00069
00070 parseEdge(attrs);
00071 break;
00072 case SUMO_TAG_LANE:
00073 if (myProcess) {
00074 parseLane(attrs);
00075 }
00076 break;
00077 case SUMO_TAG_JUNCTION:
00078 parseJunction(attrs);
00079 break;
00080 case SUMO_TAG_SUCC:
00081 parseConnectingEdge(attrs);
00082 break;
00083 case SUMO_TAG_SUCCLANE:
00084 parseConnectedEdge(attrs);
00085 break;
00086 case SUMO_TAG_DISTRICT:
00087 parseDistrict(attrs);
00088 break;
00089 case SUMO_TAG_DSOURCE:
00090 parseDistrictEdge(attrs, true);
00091 break;
00092 case SUMO_TAG_DSINK:
00093 parseDistrictEdge(attrs, false);
00094 break;
00095 default:
00096 break;
00097 }
00098 }
00099
00100
00101 void
00102 RONetHandler::parseEdge(const SUMOSAXAttributes &attrs) {
00103
00104 if (!attrs.setIDFromAttributes("edge", myCurrentName)) {
00105 throw ProcessError();
00106 }
00107
00108 myCurrentEdge = 0;
00109 if (myCurrentName[0]==':') {
00110
00111
00112 return;
00113 }
00114 bool ok = true;
00115 std::string from = attrs.getStringReporting(SUMO_ATTR_FROM, "edge", myCurrentName.c_str(), ok);
00116 std::string to = attrs.getStringReporting(SUMO_ATTR_TO, "edge", myCurrentName.c_str(), ok);
00117 std::string type = attrs.getStringReporting(SUMO_ATTR_FUNCTION, "edge", myCurrentName.c_str(), ok);
00118 if (!ok) {
00119 return;
00120 }
00121 RONode *fromNode = myNet.getNode(from);
00122 if (fromNode==0) {
00123 fromNode = new RONode(from);
00124 myNet.addNode(fromNode);
00125 }
00126 RONode *toNode = myNet.getNode(to);
00127 if (toNode==0) {
00128 toNode = new RONode(to);
00129 myNet.addNode(toNode);
00130 }
00131
00132 myCurrentEdge = myEdgeBuilder.buildEdge(myCurrentName, fromNode, toNode);
00133 myNet.addEdge(myCurrentEdge);
00134
00135
00136 myProcess = true;
00137 if (type=="normal"||type=="connector") {
00138 myCurrentEdge->setType(ROEdge::ET_NORMAL);
00139 } else if (type=="source") {
00140 myCurrentEdge->setType(ROEdge::ET_SOURCE);
00141 } else if (type=="sink") {
00142 myCurrentEdge->setType(ROEdge::ET_SINK);
00143 } else if (type=="internal") {
00144 myProcess = false;
00145 } else {
00146 MsgHandler::getErrorInstance()->inform("Edge '" + myCurrentName + "' has an unknown type.");
00147 return;
00148 }
00149 }
00150
00151
00152 void
00153 RONetHandler::parseLane(const SUMOSAXAttributes &attrs) {
00154 if (myCurrentEdge==0) {
00155
00156 return;
00157 }
00158 std::vector<SUMOVehicleClass> allowed, disallowed;
00159
00160 std::string id;
00161 if (!attrs.setIDFromAttributes("lane", id)) {
00162 return;
00163 }
00164
00165 bool ok = true;
00166 SUMOReal maxSpeed = attrs.getSUMORealReporting(SUMO_ATTR_MAXSPEED, "lane", id.c_str(), ok);
00167 SUMOReal length = attrs.getSUMORealReporting(SUMO_ATTR_LENGTH, "lane", id.c_str(), ok);
00168 std::string vclasses = attrs.getOptStringReporting(SUMO_ATTR_VCLASSES, "lane", id.c_str(), ok, "");
00169 std::string allow = attrs.getOptStringReporting(SUMO_ATTR_ALLOW, "lane", id.c_str(), ok, "");
00170 std::string disallow = attrs.getOptStringReporting(SUMO_ATTR_DISALLOW, "lane", id.c_str(), ok, "");
00171 if (!ok) {
00172 return;
00173 }
00174
00175
00176 parseVehicleClasses(vclasses, allow, disallow,
00177 allowed, disallowed, myHaveWarnedAboutDeprecatedVClass);
00178 if (allowed.size()!=0 || disallowed.size() != 0) {
00179 myNet.setRestrictionFound();
00180 }
00181
00182 if (maxSpeed>0&&length>0&&id.length()>0) {
00183 myCurrentEdge->addLane(new ROLane(id, length, maxSpeed, allowed, disallowed));
00184 }
00185 }
00186
00187
00188 void
00189 RONetHandler::parseJunction(const SUMOSAXAttributes &attrs) {
00190
00191 std::string id;
00192 if (!attrs.setIDFromAttributes("junction", id)) {
00193 return;
00194 }
00195
00196 bool ok = true;
00197 SUMOReal x = attrs.getSUMORealReporting(SUMO_ATTR_X, "junction", id.c_str(), ok);
00198 SUMOReal y = attrs.getSUMORealReporting(SUMO_ATTR_Y, "junction", id.c_str(), ok);
00199 if (ok) {
00200 RONode *n = myNet.getNode(id);
00201 if (n==0) {
00202 n = new RONode(id);
00203 myNet.addNode(n);
00204 }
00205 n->setPosition(Position2D(x, y));
00206 } else {
00207 throw ProcessError();
00208 }
00209 }
00210
00211
00212 void
00213 RONetHandler::parseConnectingEdge(const SUMOSAXAttributes &attrs) throw(ProcessError) {
00214 bool ok = true;
00215 std::string id = attrs.getStringReporting(SUMO_ATTR_EDGE, 0,0, ok);
00216 if (id[0]==':') {
00217 myCurrentEdge = 0;
00218 return;
00219 }
00220 myCurrentEdge = myNet.getEdge(id);
00221 if (myCurrentEdge==0) {
00222 throw ProcessError("An unknown edge occured (id='" + id + "').");
00223 }
00224 }
00225
00226
00227 void
00228 RONetHandler::parseConnectedEdge(const SUMOSAXAttributes &attrs) {
00229 if (myCurrentEdge==0) {
00230
00231 return;
00232 }
00233 bool ok = true;
00234 std::string id = attrs.getStringReporting(SUMO_ATTR_LANE, "lane", myCurrentName.c_str(), ok);
00235 if (id=="SUMO_NO_DESTINATION") {
00236 return;
00237 }
00238 ROEdge *succ = myNet.getEdge(id.substr(0, id.rfind('_')));
00239 if (succ!=0) {
00240
00241 myCurrentEdge->addFollower(succ);
00242 } else {
00243 MsgHandler::getErrorInstance()->inform("At edge '" + myCurrentName + "': succeeding edge '" + id + "' does not exist.");
00244 }
00245 }
00246
00247
00248 void
00249 RONetHandler::parseDistrict(const SUMOSAXAttributes &attrs) throw(ProcessError) {
00250 if (!attrs.setIDFromAttributes("district", myCurrentName)) {
00251 return;
00252 }
00253 myCurrentEdge = myEdgeBuilder.buildEdge(myCurrentName, 0, 0);
00254 myCurrentEdge->setType(ROEdge::ET_DISTRICT);
00255 myNet.addEdge(myCurrentEdge);
00256 myCurrentEdge = myEdgeBuilder.buildEdge(myCurrentName + "-source", 0, 0);
00257 myCurrentEdge->setType(ROEdge::ET_DISTRICT);
00258 myNet.addEdge(myCurrentEdge);
00259 if (attrs.hasAttribute(SUMO_ATTR_EDGES)) {
00260 std::vector<std::string> desc = StringTokenizer(attrs.getString(SUMO_ATTR_EDGES)).getVector();
00261 for (std::vector<std::string>::const_iterator i=desc.begin(); i!=desc.end(); ++i) {
00262 ROEdge *edge = myNet.getEdge(*i);
00263
00264 if (edge==0) {
00265 throw ProcessError("The edge '" + *i + "' within district '" + myCurrentName + "' is not known.");
00266 }
00267 myCurrentEdge->addFollower(edge);
00268 edge->addFollower(myNet.getEdge(myCurrentName));
00269 }
00270 }
00271 }
00272
00273
00274 void
00275 RONetHandler::parseDistrictEdge(const SUMOSAXAttributes &attrs, bool isSource) {
00276 if (myCurrentEdge==0) {
00277
00278 return;
00279 }
00280 bool ok = true;
00281 std::string id = attrs.getStringReporting(SUMO_ATTR_ID, "district", myCurrentName.c_str(), ok);
00282 ROEdge *succ = myNet.getEdge(id);
00283 if (succ!=0) {
00284
00285 if (isSource) {
00286 myCurrentEdge->addFollower(succ);
00287 } else {
00288 succ->addFollower(myNet.getEdge(myCurrentName));
00289 }
00290 } else {
00291 MsgHandler::getErrorInstance()->inform("At district '" + myCurrentName + "': succeeding edge '" + id + "' does not exist.");
00292 }
00293 }
00294
00295
00296
00297
00298