00001
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #ifdef _MSC_VER
00023 #include <windows_config.h>
00024 #else
00025 #include <config.h>
00026 #endif
00027
00028 #include <string>
00029 #include "NLHandler.h"
00030 #include "NLEdgeControlBuilder.h"
00031 #include "NLJunctionControlBuilder.h"
00032 #include "NLDetectorBuilder.h"
00033 #include "NLTriggerBuilder.h"
00034 #include <utils/xml/SUMOXMLDefinitions.h>
00035 #include <utils/xml/SUMOSAXHandler.h>
00036 #include <utils/common/MsgHandler.h>
00037 #include <utils/common/SUMOTime.h>
00038 #include <utils/common/TplConvert.h>
00039 #include <utils/common/TplConvertSec.h>
00040 #include <utils/common/StringTokenizer.h>
00041 #include <utils/common/RGBColor.h>
00042 #include <utils/geom/GeomConvHelper.h>
00043 #include <microsim/MSGlobals.h>
00044 #include <microsim/MSBitSetLogic.h>
00045 #include <microsim/MSJunctionLogic.h>
00046 #include <microsim/traffic_lights/MSTrafficLightLogic.h>
00047 #include <microsim/output/MSInductLoop.h>
00048 #include <microsim/output/MSE2Collector.h>
00049 #include <microsim/output/MS_E2_ZS_CollectorOverLanes.h>
00050 #include <microsim/traffic_lights/MSAgentbasedTrafficLightLogic.h>
00051 #include <utils/iodevices/OutputDevice.h>
00052 #include <utils/common/UtilExceptions.h>
00053 #include <utils/geom/GeoConvHelper.h>
00054 #include "NLGeomShapeBuilder.h"
00055
00056 #ifdef CHECK_MEMORY_LEAKS
00057 #include <foreign/nvwa/debug_new.h>
00058 #endif // CHECK_MEMORY_LEAKS
00059
00060
00061
00062
00063
00064 NLHandler::NLHandler(const std::string &file, MSNet &net,
00065 NLDetectorBuilder &detBuilder,
00066 NLTriggerBuilder &triggerBuilder,
00067 NLEdgeControlBuilder &edgeBuilder,
00068 NLJunctionControlBuilder &junctionBuilder,
00069 NLGeomShapeBuilder &shapeBuilder) throw()
00070 : MSRouteHandler(file, true),
00071 myNet(net), myActionBuilder(net),
00072 myCurrentIsInternalToSkip(false),
00073 myDetectorBuilder(detBuilder), myTriggerBuilder(triggerBuilder),
00074 myEdgeControlBuilder(edgeBuilder), myJunctionControlBuilder(junctionBuilder),
00075 myShapeBuilder(shapeBuilder), mySucceedingLaneBuilder(junctionBuilder),
00076 myAmInTLLogicMode(false), myCurrentIsBroken(false),
00077 myHaveWarnedAboutDeprecatedVClass(false),
00078 myHaveWarnedAboutDeprecatedJunctionShape(false),
00079 myHaveWarnedAboutDeprecatedLaneShape(false),
00080 myHaveWarnedAboutDeprecatedPolyShape(false),
00081 myHaveWarnedAboutDeprecatedLocation(false),
00082 myHaveWarnedAboutDeprecatedPhases(false) {}
00083
00084
00085 NLHandler::~NLHandler() throw() {}
00086
00087
00088 void
00089 NLHandler::myStartElement(SumoXMLTag element,
00090 const SUMOSAXAttributes &attrs) throw(ProcessError) {
00091 try {
00092 switch (element) {
00093 case SUMO_TAG_EDGE:
00094 beginEdgeParsing(attrs);
00095 break;
00096 case SUMO_TAG_LANE:
00097 addLane(attrs);
00098 break;
00099 case SUMO_TAG_POLY:
00100 addPoly(attrs);
00101 break;
00102 case SUMO_TAG_POI:
00103 addPOI(attrs);
00104 break;
00105 case SUMO_TAG_JUNCTION:
00106 openJunction(attrs);
00107 break;
00108 case SUMO_TAG_PHASE:
00109 addPhase(attrs);
00110 break;
00111 case SUMO_TAG_SUCC:
00112 openSucc(attrs);
00113 break;
00114 case SUMO_TAG_SUCCLANE:
00115 addSuccLane(attrs);
00116 break;
00117 case SUMO_TAG_ROWLOGIC:
00118 initJunctionLogic(attrs);
00119 break;
00120 case SUMO_TAG_TLLOGIC:
00121 initTrafficLightLogic(attrs);
00122 break;
00123 case SUMO_TAG_LOGICITEM:
00124 addLogicItem(attrs);
00125 break;
00126 case SUMO_TAG_WAUT:
00127 openWAUT(attrs);
00128 break;
00129 case SUMO_TAG_WAUT_SWITCH:
00130 addWAUTSwitch(attrs);
00131 break;
00132 case SUMO_TAG_WAUT_JUNCTION:
00133 addWAUTJunction(attrs);
00134 break;
00136 case SUMO_TAG_DETECTOR:
00137 addDetector(attrs);
00138 break;
00140 #ifdef _MESSAGES
00141 case SUMO_TAG_MSG_EMITTER:
00142 addMsgEmitter(attrs);
00143 break;
00144 case SUMO_TAG_MSG:
00145 addMsgDetector(attrs);
00146 break;
00147 #endif
00148 case SUMO_TAG_E1DETECTOR:
00149 addE1Detector(attrs);
00150 break;
00151 case SUMO_TAG_E2DETECTOR:
00152 addE2Detector(attrs);
00153 break;
00154 case SUMO_TAG_E3DETECTOR:
00155 beginE3Detector(attrs);
00156 break;
00157 case SUMO_TAG_DET_ENTRY:
00158 addE3Entry(attrs);
00159 break;
00160 case SUMO_TAG_DET_EXIT:
00161 addE3Exit(attrs);
00162 break;
00163 case SUMO_TAG_VSS:
00164 myTriggerBuilder.parseAndBuildLaneSpeedTrigger(myNet, attrs, getFileName());
00165 break;
00166 case SUMO_TAG_EMITTER:
00167 myTriggerBuilder.parseAndBuildLaneEmitTrigger(myNet, attrs, getFileName());
00168 break;
00169 case SUMO_TAG_CALIBRATOR:
00170 myTriggerBuilder.parseAndBuildCalibrator(myNet, attrs, getFileName());
00171 break;
00172 case SUMO_TAG_REROUTER:
00173 myTriggerBuilder.parseAndBuildRerouter(myNet, attrs, getFileName());
00174 break;
00175 case SUMO_TAG_BUS_STOP:
00176 myTriggerBuilder.parseAndBuildBusStop(myNet, attrs);
00177 break;
00178 case SUMO_TAG_VTYPEPROBE:
00179 addVTypeProbeDetector(attrs);
00180 break;
00181 case SUMO_TAG_ROUTEPROBE:
00182 addRouteProbeDetector(attrs);
00183 break;
00184 case SUMO_TAG_MEANDATA_EDGE:
00185 addEdgeLaneMeanData(attrs, "meandata_edge");
00186 break;
00187 case SUMO_TAG_MEANDATA_LANE:
00188 addEdgeLaneMeanData(attrs, "meandata_lane");
00189 break;
00190 case SUMO_TAG_SOURCE:
00191 addSource(attrs);
00192 break;
00193 case SUMO_TAG_TRIGGER:
00194 addTrigger(attrs);
00195 break;
00196 case SUMO_TAG_TIMEDEVENT:
00197 myActionBuilder.addAction(attrs, getFileName());
00198 break;
00199 case SUMO_TAG_VAPORIZER:
00200 myTriggerBuilder.buildVaporizer(attrs);
00201 break;
00202 case SUMO_TAG_LOCATION:
00203 setLocation(attrs);
00204 break;
00205 case SUMO_TAG_DISTRICT:
00206 addDistrict(attrs);
00207 break;
00208 case SUMO_TAG_DSOURCE:
00209 addDistrictEdge(attrs, true);
00210 break;
00211 case SUMO_TAG_DSINK:
00212 addDistrictEdge(attrs, false);
00213 break;
00214 default:
00215 break;
00216 }
00217 } catch (InvalidArgument &e) {
00218 MsgHandler::getErrorInstance()->inform(e.what());
00219 }
00220 MSRouteHandler::myStartElement(element, attrs);
00221 if (element==SUMO_TAG_PARAM) {
00222 addParam(attrs);
00223 }
00224 }
00225
00226
00227 void
00228 NLHandler::myCharacters(SumoXMLTag element,
00229 const std::string &chars) throw(ProcessError) {
00230 bool ok = true;
00231 switch (element) {
00232 case SUMO_TAG_POLY:
00233 if (chars.length()!=0) {
00234 myShapeBuilder.polygonEnd(GeomConvHelper::parseShapeReporting(chars, "polygon", 0, ok, false));
00235 }
00236 break;
00237 case SUMO_TAG_INCOMING_LANES:
00238 addIncomingLanes(chars);
00239 break;
00240 #ifdef HAVE_INTERNAL_LANES
00241 case SUMO_TAG_INTERNAL_LANES:
00242 addInternalLanes(chars);
00243 break;
00244 #endif
00245 case SUMO_TAG_LANE:
00246 if (chars.length()!=0) {
00247 addLaneShape(chars);
00248 }
00249 break;
00250 case SUMO_TAG_REQUESTSIZE:
00251 if (myJunctionControlBuilder.getActiveKey().length()!=0) {
00252 setRequestSize(chars);
00253 }
00254 break;
00255 case SUMO_TAG_LANENUMBER:
00256 if (myJunctionControlBuilder.getActiveKey().length()!=0) {
00257 setLaneNumber(chars);
00258 }
00259 break;
00260 case SUMO_TAG_KEY:
00261 setKey(chars);
00262 break;
00263 case SUMO_TAG_SUBKEY:
00264 setSubKey(chars);
00265 break;
00266 case SUMO_TAG_OFFSET:
00267 setOffset(chars);
00268 break;
00269 case SUMO_TAG_NET_OFFSET: {
00270 if (!myHaveWarnedAboutDeprecatedLocation) {
00271 myHaveWarnedAboutDeprecatedLocation = true;
00272 MsgHandler::getWarningInstance()->inform("Your network uses a deprecated network offset/projection definition.");
00273 }
00274 Position2DVector s = GeomConvHelper::parseShapeReporting(chars, "net", 0, ok, false);
00275 if (ok) {
00276 myNetworkOffset = s[0];
00277 }
00278 }
00279 break;
00280 case SUMO_TAG_CONV_BOUNDARY:
00281 myConvBoundary = GeomConvHelper::parseBoundaryReporting(chars, "net", 0, ok);
00282 break;
00283 case SUMO_TAG_ORIG_BOUNDARY:
00284 myOrigBoundary = GeomConvHelper::parseBoundaryReporting(chars, "net", 0, ok);
00285 break;
00286 case SUMO_TAG_ORIG_PROJ:
00287 GeoConvHelper::init(chars, myNetworkOffset, myOrigBoundary, myConvBoundary);
00288 break;
00289 case SUMO_TAG_SHAPE:
00290 if (chars.length()!=0) {
00291 addJunctionShape(chars);
00292 }
00293 break;
00294 default:
00295 break;
00296 }
00297 MSRouteHandler::myCharacters(element, chars);
00298 }
00299
00300
00301 void
00302 NLHandler::myEndElement(SumoXMLTag element) throw(ProcessError) {
00303 switch (element) {
00304 case SUMO_TAG_EDGE:
00305 closeEdge();
00306 break;
00307 case SUMO_TAG_LANE:
00308 closeLane();
00309 break;
00310 case SUMO_TAG_JUNCTION:
00311 closeJunction();
00312 break;
00313 case SUMO_TAG_SUCC:
00314 closeSuccLane();
00315 break;
00316 case SUMO_TAG_ROWLOGIC:
00317 try {
00318 myJunctionControlBuilder.closeJunctionLogic();
00319 } catch (InvalidArgument &e) {
00320 MsgHandler::getErrorInstance()->inform(e.what());
00321 }
00322 break;
00323 case SUMO_TAG_TLLOGIC:
00324 try {
00325 myJunctionControlBuilder.closeTrafficLightLogic();
00326 } catch (InvalidArgument &e) {
00327 MsgHandler::getErrorInstance()->inform(e.what());
00328 }
00329 myAmInTLLogicMode = false;
00330 break;
00331 case SUMO_TAG_WAUT:
00332 closeWAUT();
00333 break;
00334 case SUMO_TAG_E3DETECTOR:
00335 endE3Detector();
00336 break;
00337 case SUMO_TAG_DETECTOR:
00338 endDetector();
00339 break;
00340 default:
00341 break;
00342 }
00343 MSRouteHandler::myEndElement(element);
00344 }
00345
00346
00347
00348
00349 void
00350 NLHandler::beginEdgeParsing(const SUMOSAXAttributes &attrs) {
00351 myCurrentIsBroken = false;
00352
00353 std::string id;
00354 if (!attrs.setIDFromAttributes("edge", id)) {
00355 myCurrentIsBroken = true;
00356 return;
00357 }
00358
00359 if (!MSGlobals::gUsingInternalLanes&&id[0]==':') {
00360 myCurrentIsInternalToSkip = true;
00361 return;
00362 }
00363 myCurrentIsInternalToSkip = false;
00364
00365 bool ok = true;
00366 std::string func = attrs.getStringReporting(SUMO_ATTR_FUNCTION, "edge", id.c_str(), ok);
00367 if (!ok) {
00368 myCurrentIsBroken = true;
00369 return;
00370 }
00371
00372 MSEdge::EdgeBasicFunction funcEnum = MSEdge::EDGEFUNCTION_UNKNOWN;
00373 if (func=="normal") {
00374 funcEnum = MSEdge::EDGEFUNCTION_NORMAL;
00375 } else if (func=="connector"||func=="sink"||func=="source") {
00376 funcEnum = MSEdge::EDGEFUNCTION_CONNECTOR;
00377 } else if (func=="internal") {
00378 funcEnum = MSEdge::EDGEFUNCTION_INTERNAL;
00379 }
00380 if (funcEnum<0) {
00381 MsgHandler::getErrorInstance()->inform("Edge '" + id + "' has an invalid type ('" + func + "').");
00382 myCurrentIsBroken = true;
00383 return;
00384 }
00385
00386 try {
00387 myEdgeControlBuilder.beginEdgeParsing(id, funcEnum);
00388 } catch (InvalidArgument &e) {
00389 MsgHandler::getErrorInstance()->inform(e.what());
00390 myCurrentIsBroken = true;
00391 }
00392 }
00393
00394
00395 void
00396 NLHandler::closeEdge() {
00397
00398 if (myCurrentIsInternalToSkip||myCurrentIsBroken) {
00399 return;
00400 }
00401 try {
00402 MSEdge& edge = *myEdgeControlBuilder.closeEdge();
00403 } catch (InvalidArgument &e) {
00404 MsgHandler::getErrorInstance()->inform(e.what());
00405 }
00406 }
00407
00408
00409
00410 void
00411 NLHandler::addLane(const SUMOSAXAttributes &attrs) {
00412 myShape.clear();
00413
00414 if (myCurrentIsInternalToSkip||myCurrentIsBroken) {
00415 return;
00416 }
00417
00418 if (!attrs.setIDFromAttributes("lane", myCurrentLaneID)) {
00419 myCurrentIsBroken = true;
00420 return;
00421 }
00422 bool ok = true;
00423 myLaneIsDepart = attrs.getBoolReporting(SUMO_ATTR_DEPART, "lane", myCurrentLaneID.c_str(), ok);
00424 myCurrentMaxSpeed = attrs.getSUMORealReporting(SUMO_ATTR_MAXSPEED, "lane", myCurrentLaneID.c_str(), ok);
00425 myCurrentLength = attrs.getSUMORealReporting(SUMO_ATTR_LENGTH, "lane", myCurrentLaneID.c_str(), ok);
00426 std::string allow = attrs.getOptStringReporting(SUMO_ATTR_ALLOW, "lane", myCurrentLaneID.c_str(), ok, "");
00427 std::string disallow = attrs.getOptStringReporting(SUMO_ATTR_DISALLOW, "lane", myCurrentLaneID.c_str(), ok, "");
00428 std::string vclasses = attrs.getOptStringReporting(SUMO_ATTR_VCLASSES, "lane", myCurrentLaneID.c_str(), ok, "");
00429 myAllowedClasses.clear();
00430 myDisallowedClasses.clear();
00431 parseVehicleClasses(vclasses, allow, disallow, myAllowedClasses, myDisallowedClasses, myHaveWarnedAboutDeprecatedVClass);
00432 myCurrentIsBroken |= !ok;
00433 if (!myCurrentIsBroken) {
00434 if (attrs.hasAttribute(SUMO_ATTR_SHAPE)) {
00435 addLaneShape(attrs.getStringReporting(SUMO_ATTR_SHAPE, "lane", myCurrentLaneID.c_str(), ok));
00436 } else if (!myHaveWarnedAboutDeprecatedLaneShape) {
00437 myHaveWarnedAboutDeprecatedLaneShape = true;
00438 MsgHandler::getWarningInstance()->inform("Your network uses a deprecated lane shape description; please rebuild.");
00439 }
00440 }
00441 }
00442
00443
00444 void
00445 NLHandler::addLaneShape(const std::string &chars) {
00446
00447 if (myCurrentIsInternalToSkip||myCurrentIsBroken) {
00448 return;
00449 }
00450 bool ok = true;
00451 myShape = GeomConvHelper::parseShapeReporting(chars, "lane", myCurrentLaneID.c_str(), ok, false);
00452 if (!ok) {
00453 MsgHandler::getErrorInstance()->inform("Could not parse shape of lane '" + myCurrentLaneID + "'.\n Can not build according edge.");
00454 myCurrentIsBroken = true;
00455 }
00456 }
00457
00458
00459 void
00460 NLHandler::closeLane() {
00461
00462 if (myCurrentIsInternalToSkip||myCurrentIsBroken) {
00463 return;
00464 }
00465
00466 if (myShape.size()<2) {
00467 MsgHandler::getErrorInstance()->inform("Shape of lane '" + myCurrentLaneID + "' is broken.\n Can not build according edge.");
00468 myCurrentIsBroken = true;
00469 return;
00470 }
00471
00472 try {
00473 MSLane *lane =
00474 myEdgeControlBuilder.addLane(myCurrentLaneID, myCurrentMaxSpeed, myCurrentLength, myLaneIsDepart, myShape, myAllowedClasses, myDisallowedClasses);
00475
00476 if (!MSLane::dictionary(myCurrentLaneID, lane)) {
00477 delete lane;
00478 MsgHandler::getErrorInstance()->inform("Another lane with the id '" + myCurrentLaneID + "' exists.");
00479 myCurrentIsBroken = true;
00480 }
00481 } catch (InvalidArgument &e) {
00482 MsgHandler::getErrorInstance()->inform(e.what());
00483 }
00484 }
00485
00486
00487
00488 void
00489 NLHandler::openJunction(const SUMOSAXAttributes &attrs) {
00490 myCurrentIsBroken = false;
00491
00492 std::string id;
00493 if (!attrs.setIDFromAttributes("junction", id)) {
00494 myCurrentIsBroken = true;
00495 return;
00496 }
00497 bool ok = true;
00498 Position2DVector shape;
00499 if (attrs.hasAttribute(SUMO_ATTR_SHAPE)) {
00500
00501 shape = GeomConvHelper::parseShapeReporting(attrs.getStringSecure(SUMO_ATTR_SHAPE, ""), "junction", id.c_str(), ok, true);
00502 }
00503 SUMOReal x = attrs.getSUMORealReporting(SUMO_ATTR_X, "junction", id.c_str(), ok);
00504 SUMOReal y = attrs.getSUMORealReporting(SUMO_ATTR_Y, "junction", id.c_str(), ok);
00505 std::string type = attrs.getStringReporting(SUMO_ATTR_TYPE, "junction", id.c_str(), ok);
00506 std::string key = attrs.getOptStringReporting(SUMO_ATTR_KEY, "junction", id.c_str(), ok, "");
00507 if (!ok) {
00508 myCurrentIsBroken = true;
00509 } else {
00510 try {
00511 myJunctionControlBuilder.openJunction(id, key, type, x, y, shape);
00512 } catch (InvalidArgument &e) {
00513 MsgHandler::getErrorInstance()->inform(e.what() + std::string("\n Can not build according junction."));
00514 myCurrentIsBroken = true;
00515 }
00516
00517 if (!myCurrentIsBroken&&attrs.hasAttribute(SUMO_ATTR_INCLANES)) {
00518 addIncomingLanes(attrs.getStringSecure(SUMO_ATTR_INCLANES, ""));
00519 }
00520 #ifdef HAVE_INTERNAL_LANES
00521 if (!myCurrentIsBroken&&attrs.hasAttribute(SUMO_ATTR_INTLANES)) {
00522 addInternalLanes(attrs.getStringSecure(SUMO_ATTR_INTLANES, ""));
00523 }
00524 #endif
00525 }
00526 }
00527
00528
00529 void
00530 NLHandler::closeJunction() {
00531 if (myCurrentIsBroken) {
00532 return;
00533 }
00534 try {
00535 myJunctionControlBuilder.closeJunction();
00536 } catch (InvalidArgument &e) {
00537 MsgHandler::getErrorInstance()->inform(e.what());
00538 }
00539 }
00540
00541
00542 void
00543 NLHandler::addParam(const SUMOSAXAttributes &attrs) {
00544 bool ok = true;
00545 std::string key = attrs.getStringReporting(SUMO_ATTR_KEY, 0, 0, ok);
00546 std::string val = attrs.getStringReporting(SUMO_ATTR_VALUE, 0, 0, ok);
00547
00548 if (ok&&myAmInTLLogicMode) {
00549 assert(key!="");
00550 assert(val!="");
00551 myJunctionControlBuilder.addParam(key, val);
00552 }
00553 }
00554
00555
00556 void
00557 NLHandler::openWAUT(const SUMOSAXAttributes &attrs) {
00558 myCurrentIsBroken = false;
00559
00560
00561 std::string id;
00562 if (!attrs.setIDFromAttributes("waut", id)) {
00563 myCurrentIsBroken = true;
00564 return;
00565 }
00566 bool ok = true;
00567 SUMOTime t = attrs.getOptSUMOTimeReporting(SUMO_ATTR_REF_TIME, "waut", id.c_str(), ok, 0);
00568 std::string pro = attrs.getStringReporting(SUMO_ATTR_START_PROG, "waut", id.c_str(), ok);
00569 if (!ok) {
00570 myCurrentIsBroken = true;
00571 }
00572 if (!myCurrentIsBroken) {
00573 myCurrentWAUTID = id;
00574 try {
00575 myJunctionControlBuilder.getTLLogicControlToUse().addWAUT(t, id, pro);
00576 } catch (InvalidArgument &e) {
00577 MsgHandler::getErrorInstance()->inform(e.what());
00578 myCurrentIsBroken = true;
00579 }
00580 }
00581 }
00582
00583
00584 void
00585 NLHandler::addWAUTSwitch(const SUMOSAXAttributes &attrs) {
00586 bool ok = true;
00587 SUMOTime t = attrs.getSUMOTimeReporting(SUMO_ATTR_TIME, "wautSwitch", myCurrentWAUTID.c_str(), ok);
00588 std::string to = attrs.getStringReporting(SUMO_ATTR_TO, "wautSwitch", myCurrentWAUTID.c_str(), ok);
00589 if (!ok) {
00590 myCurrentIsBroken = true;
00591 }
00592 if (!myCurrentIsBroken) {
00593 try {
00594 myJunctionControlBuilder.getTLLogicControlToUse().addWAUTSwitch(myCurrentWAUTID, t, to);
00595 } catch (InvalidArgument &e) {
00596 MsgHandler::getErrorInstance()->inform(e.what());
00597 myCurrentIsBroken = true;
00598 }
00599 }
00600 }
00601
00602
00603 void
00604 NLHandler::addWAUTJunction(const SUMOSAXAttributes &attrs) {
00605 bool ok = true;
00606 std::string wautID = attrs.getStringReporting(SUMO_ATTR_WAUT_ID, "wautJunction", 0, ok);
00607 std::string junctionID = attrs.getStringReporting(SUMO_ATTR_JUNCTION_ID, "wautJunction", 0, ok);
00608 std::string procedure = attrs.getOptStringReporting(SUMO_ATTR_PROCEDURE, "wautJunction", 0, ok, "");
00609 bool synchron = attrs.getOptBoolReporting(SUMO_ATTR_SYNCHRON, "wautJunction", 0, ok, false);
00610 if (!ok) {
00611 myCurrentIsBroken = true;
00612 }
00613 try {
00614 if (!myCurrentIsBroken) {
00615 myJunctionControlBuilder.getTLLogicControlToUse().addWAUTJunction(wautID, junctionID, procedure, synchron);
00616 }
00617 } catch (InvalidArgument &e) {
00618 MsgHandler::getErrorInstance()->inform(e.what());
00619 myCurrentIsBroken = true;
00620 }
00621 }
00622
00623
00624
00625
00626
00627
00628
00629 void
00630 NLHandler::addPOI(const SUMOSAXAttributes &attrs) {
00631
00632 std::string id;
00633 if (!attrs.setIDFromAttributes("poi", id)) {
00634 return;
00635 }
00636 bool ok = true;
00637 SUMOReal x = attrs.getOptSUMORealReporting(SUMO_ATTR_X, "poi", id.c_str(), ok, INVALID_POSITION);
00638 SUMOReal y = attrs.getOptSUMORealReporting(SUMO_ATTR_Y, "poi", id.c_str(), ok, INVALID_POSITION);
00639 SUMOReal lanePos = attrs.getOptSUMORealReporting(SUMO_ATTR_POSITION, "poi", id.c_str(), ok, INVALID_POSITION);
00640 int layer = attrs.getOptIntReporting(SUMO_ATTR_LAYER, "poi", id.c_str(), ok, 1);
00641 std::string type = attrs.getOptStringReporting(SUMO_ATTR_TYPE, "poi", id.c_str(), ok, "");
00642 std::string lane = attrs.getOptStringReporting(SUMO_ATTR_LANE, "poi", id.c_str(), ok, "");
00643 std::string colorStr = attrs.getOptStringReporting(SUMO_ATTR_COLOR, "poi", id.c_str(), ok, "1,0,0");
00644 RGBColor color = RGBColor::parseColorReporting(colorStr, "poi", id.c_str(), true, ok);
00645 if (!ok) {
00646 return;
00647 }
00648 try {
00649 myShapeBuilder.addPoint(id, layer, type, color, x, y, lane, lanePos);
00650 } catch (InvalidArgument &e) {
00651 MsgHandler::getErrorInstance()->inform(e.what());
00652 } catch (OutOfBoundsException &) {
00653 MsgHandler::getErrorInstance()->inform("Color definition of POI '" + id + "' seems to be broken.");
00654 } catch (NumberFormatException &) {
00655 MsgHandler::getErrorInstance()->inform("One of POI's '" + id + "' SUMOSAXAttributes should be numeric but is not.");
00656 }
00657 }
00658
00659
00660 void
00661 NLHandler::addPoly(const SUMOSAXAttributes &attrs) {
00662
00663 std::string id;
00664 if (!attrs.setIDFromAttributes("poly", id)) {
00665 return;
00666 }
00667 bool ok = true;
00668 int layer = attrs.getOptIntReporting(SUMO_ATTR_LAYER, "poly", id.c_str(), ok, 1);
00669 bool fill = attrs.getOptBoolReporting(SUMO_ATTR_FILL, "poly", id.c_str(), ok, false);
00670 std::string type = attrs.getOptStringReporting(SUMO_ATTR_TYPE, "poly", id.c_str(), ok, "");
00671 std::string colorStr = attrs.getStringReporting(SUMO_ATTR_COLOR, "poly", id.c_str(), ok);
00672 RGBColor color = RGBColor::parseColorReporting(colorStr, "poi", id.c_str(), true, ok);
00673 if (!ok) {
00674 return;
00675 }
00676 myShapeBuilder.polygonBegin(id, layer, type, color, fill);
00677 if (attrs.hasAttribute(SUMO_ATTR_SHAPE)) {
00678
00679 myShapeBuilder.polygonEnd(GeomConvHelper::parseShapeReporting(attrs.getStringReporting(SUMO_ATTR_SHAPE, "poly", id.c_str(), ok), "poly", id.c_str(), ok, false));
00680 } else if (!myHaveWarnedAboutDeprecatedPolyShape) {
00681 myHaveWarnedAboutDeprecatedPolyShape = true;
00682 MsgHandler::getWarningInstance()->inform("You use a deprecated polygon shape description; use attribute 'shape' instead.");
00683 }
00684 }
00685
00686
00687 void
00688 NLHandler::addLogicItem(const SUMOSAXAttributes &attrs) {
00689 bool ok = true;
00690 int request = attrs.getIntReporting(SUMO_ATTR_REQUEST, "request", 0, ok);
00691 bool cont = false;
00692 #ifdef HAVE_INTERNAL_LANES
00693 cont = attrs.getOptBoolReporting(SUMO_ATTR_CONT, 0, 0, ok, false);
00694 #endif
00695 std::string response = attrs.getStringReporting(SUMO_ATTR_RESPONSE, 0, 0, ok);
00696 std::string foes = attrs.getStringReporting(SUMO_ATTR_FOES, 0, 0, ok);
00697 if (!ok) {
00698 return;
00699 }
00700
00701 if (request>=0 && response.length()>0) {
00702 try {
00703 myJunctionControlBuilder.addLogicItem(request, response, foes, cont);
00704 } catch (InvalidArgument &e) {
00705 MsgHandler::getErrorInstance()->inform(e.what());
00706 }
00707 }
00708 }
00709
00710
00711 void
00712 NLHandler::initJunctionLogic(const SUMOSAXAttributes &attrs) {
00713 if (!attrs.hasAttribute(SUMO_ATTR_ID)) {
00714
00715 myJunctionControlBuilder.initJunctionLogic("", -1, -1);
00716 return;
00717 }
00718
00719 std::string id;
00720 if (!attrs.setIDFromAttributes("row-logic", id)) {
00721 return;
00722 }
00723 bool ok = true;
00724 int requestSize = attrs.getIntReporting(SUMO_ATTR_REQUESTSIZE, "row-logic", id.c_str(), ok);
00725 int laneNumber = attrs.getIntReporting(SUMO_ATTR_LANENUMBER, "row-logic", id.c_str(), ok);
00726 if (ok) {
00727 myJunctionControlBuilder.initJunctionLogic(id, requestSize, laneNumber);
00728 }
00729 }
00730
00731
00732 void
00733 NLHandler::initTrafficLightLogic(const SUMOSAXAttributes &attrs) {
00734 SUMOReal detectorOffset = -1;
00735 myJunctionControlBuilder.initIncomingLanes();
00736 bool ok = true;
00737 std::string type = attrs.getStringReporting(SUMO_ATTR_TYPE, "tl-logic", 0, ok);
00738 detectorOffset = attrs.getOptSUMORealReporting(SUMO_ATTR_DET_OFFSET, "tl-logic", 0, ok, -1);
00739
00740 if (!attrs.hasAttribute(SUMO_ATTR_ID)) {
00741
00742 myJunctionControlBuilder.initTrafficLightLogic("", "", type, 0, detectorOffset);
00743 return;
00744 }
00745 std::string id = attrs.getStringReporting(SUMO_ATTR_ID, "tl-logic", 0, ok);
00746 int offset = attrs.getOptSUMOTimeReporting(SUMO_ATTR_OFFSET, "tl-logic", id.c_str(), ok, 0);
00747 if (!ok) {
00748 return;
00749 }
00750 std::string programID = attrs.getOptStringReporting(SUMO_ATTR_PROGRAMID, "tl-logic", id.c_str(), ok, "<unknown>");
00751 myJunctionControlBuilder.initTrafficLightLogic(id, programID, type, offset, detectorOffset);
00752 myAmInTLLogicMode = true;
00753 }
00754
00755
00756 void
00757 NLHandler::addPhase(const SUMOSAXAttributes &attrs) {
00758
00759 std::string state;
00760 std::string phase;
00761 std::string brakeMask;
00762 std::string yellowMask;
00763 bool ok = true;
00764 if (attrs.hasAttribute(SUMO_ATTR_STATE)) {
00765
00766 state = attrs.getStringReporting(SUMO_ATTR_STATE, "phase", 0, ok);
00767 } else {
00768 phase = attrs.getStringReporting(SUMO_ATTR_PHASE, "phase", 0, ok);
00769 brakeMask = attrs.getStringReporting(SUMO_ATTR_BRAKE, "phase", 0, ok);
00770 yellowMask = attrs.getStringReporting(SUMO_ATTR_YELLOW, "phase", 0, ok);
00771
00772 if (phase.length()!=brakeMask.length()||phase.length()!=yellowMask.length()) {
00773 MsgHandler::getErrorInstance()->inform("Definition of traffic light is broken - descriptions have different lengths.");
00774 return;
00775 }
00776 if (!myHaveWarnedAboutDeprecatedPhases) {
00777 myHaveWarnedAboutDeprecatedPhases = true;
00778 MsgHandler::getWarningInstance()->inform("Deprecated tls phase definition found; replace by one using states.");
00779 }
00780
00781 state = MSPhaseDefinition::old2new(phase, brakeMask, yellowMask);
00782 }
00783 if (!ok) {
00784 return;
00785 }
00786
00787 SUMOTime duration = attrs.getSUMOTimeReporting(SUMO_ATTR_DURATION, "phase", myJunctionControlBuilder.getActiveKey().c_str(), ok);
00788 if (duration==0) {
00789 MsgHandler::getErrorInstance()->inform("Duration of tls-logic '" + myJunctionControlBuilder.getActiveKey() + "/" + myJunctionControlBuilder.getActiveSubKey() + "' is zero.");
00790 return;
00791 }
00792
00793
00794 SUMOTime minDuration = attrs.getOptSUMOTimeReporting(SUMO_ATTR_MINDURATION, "phase", myJunctionControlBuilder.getActiveKey().c_str(), ok, -1);
00795 SUMOTime maxDuration = attrs.getOptSUMOTimeReporting(SUMO_ATTR_MAXDURATION, "phase", myJunctionControlBuilder.getActiveKey().c_str(), ok, -1);
00796 myJunctionControlBuilder.addPhase(duration, state, minDuration, maxDuration);
00797 }
00798
00799
00800 #ifdef _MESSAGES
00801 void
00802 NLHandler::addMsgEmitter(const SUMOSAXAttributes& attrs) {
00803 bool ok = true;
00804 std::string id = attrs.getStringReporting(SUMO_ATTR_ID, 0, 0, ok);
00805 std::string file = attrs.getOptStringReporting(SUMO_ATTR_FILE, 0, 0, ok, "");
00806
00807 if (file=="") {
00808 file = "-";
00809 }
00810 SUMOTime step = attrs.getOptSUMOTimeReporting(SUMO_ATTR_STEP, 0, id.c_str(), ok, 1);
00811 bool reverse = attrs.getOptBoolReporting(SUMO_ATTR_REVERSE, 0, 0, ok, false);
00812 bool table = attrs.getOptBoolReporting(SUMO_ATTR_TABLE, 0, 0, ok, false);
00813 bool xycoord = attrs.getOptBoolReporting(SUMO_ATTR_XY, 0, 0, ok, false);
00814 std::string whatemit = attrs.getStringReporting(SUMO_ATTR_EVENTS, 0, 0, ok);
00815 if (!ok) {
00816 return;
00817 }
00818 myNet.createMsgEmitter(id, file, getFileName(), whatemit, reverse, table, xycoord, step);
00819 }
00820 #endif
00821
00822
00823 void
00824 NLHandler::addDetector(const SUMOSAXAttributes &attrs) {
00825
00826 std::string id;
00827 if (!attrs.setIDFromAttributes("detector", id)) {
00828 return;
00829 }
00830
00831 bool ok = true;
00832 std::string type = attrs.getOptStringReporting(SUMO_ATTR_TYPE, 0, 0, ok, "induct_loop");
00833
00834
00835 if (type=="induct_loop"||type=="E1"||type=="e1") {
00836 addE1Detector(attrs);
00837 myCurrentDetectorType = "e1";
00838 return;
00839 }
00840
00841 if (type=="lane_based"||type=="E2"||type=="e2") {
00842 addE2Detector(attrs);
00843 myCurrentDetectorType = "e2";
00844 return;
00845 }
00846
00847 if (type=="multi_od"||type=="E3"||type=="e3") {
00848 beginE3Detector(attrs);
00849 myCurrentDetectorType = "e3";
00850 return;
00851 }
00852 #ifdef _MESSAGES
00853
00854 if (type=="il_msg"||type=="E4"||type=="e4") {
00855 addMsgDetector(attrs);
00856 myCurrentDetectorType="e4";
00857 }
00858 #endif
00859 }
00860
00861 #ifdef _MESSAGES
00862 void
00863 NLHandler::addMsgDetector(const SUMOSAXAttributes &attrs) {
00864
00865 std::string id;
00866 if (!attrs.setIDFromAttributes("e4-detector", id)) {
00867 return;
00868 }
00869 bool ok = true;
00870 SUMOReal position = attrs.getSUMORealReporting(SUMO_ATTR_POSITION, "e4-detector", id.c_str(), ok);
00871 bool friendlyPos = attrs.getOptBoolReporting(SUMO_ATTR_FRIENDLY_POS, "e4-detector", id.c_str(), ok, false);
00872 std::string lane = attrs.getStringReporting(SUMO_ATTR_LANE, "e4-detector", id.c_str(), ok);
00873 std::string msg = attrs.getStringReporting(SUMO_ATTR_MSG, "e4-detector", id.c_str(), ok);
00874 std::string file = attrs.getStringReporting(SUMO_ATTR_FILE, "e4-detector", id.c_str(), ok);
00875 if (!ok) {
00876 return;
00877 }
00878 try {
00879 myDetectorBuilder.buildMsgDetector(id, lane, position, 1, msg,
00880 OutputDevice::getDevice(file, getFileName()), friendlyPos);
00881 } catch (InvalidArgument &e) {
00882 MsgHandler::getErrorInstance()->inform(e.what());
00883 } catch (IOError &e) {
00884 MsgHandler::getErrorInstance()->inform(e.what());
00885 }
00886 }
00887 #endif
00888
00889
00890 void
00891 NLHandler::addE1Detector(const SUMOSAXAttributes &attrs) {
00892
00893 std::string id;
00894 if (!attrs.setIDFromAttributes("e1-detector", id)) {
00895 return;
00896 }
00897
00898 bool ok = true;
00899 if (attrs.getOptStringReporting(SUMO_ATTR_STYLE, "e1-detector", id.c_str(), ok, "<invalid>")!="<invalid>") {
00900 MsgHandler::getWarningInstance()->inform("While parsing E1-detector '" + id + "': 'style' is deprecated.");
00901 }
00902 SUMOTime frequency = attrs.getSUMOTimeReporting(SUMO_ATTR_FREQUENCY, "e1-detector", id.c_str(), ok);
00903 SUMOReal position = attrs.getSUMORealReporting(SUMO_ATTR_POSITION, "e1-detector", id.c_str(), ok);
00904 bool friendlyPos = attrs.getOptBoolReporting(SUMO_ATTR_FRIENDLY_POS, "e1-detector", id.c_str(), ok, false);
00905 std::string lane = attrs.getStringReporting(SUMO_ATTR_LANE, "e1-detector", id.c_str(), ok);
00906 std::string file = attrs.getStringReporting(SUMO_ATTR_FILE, "e1-detector", id.c_str(), ok);
00907 if (!ok) {
00908 return;
00909 }
00910 try {
00911 myDetectorBuilder.buildInductLoop(id, lane, position, frequency,
00912 OutputDevice::getDevice(file, getFileName()),
00913 friendlyPos);
00914 } catch (InvalidArgument &e) {
00915 MsgHandler::getErrorInstance()->inform(e.what());
00916 } catch (IOError &e) {
00917 MsgHandler::getErrorInstance()->inform(e.what());
00918 }
00919 }
00920
00921
00922 void
00923 NLHandler::addVTypeProbeDetector(const SUMOSAXAttributes &attrs) {
00924
00925 std::string id;
00926 if (!attrs.setIDFromAttributes("vtypeprobe", id)) {
00927 return;
00928 }
00929 bool ok = true;
00930 SUMOTime frequency = attrs.getSUMOTimeReporting(SUMO_ATTR_FREQUENCY, "vtypeprobe", id.c_str(), ok);
00931 std::string type = attrs.getStringSecure(SUMO_ATTR_TYPE, "");
00932 std::string file = attrs.getStringReporting(SUMO_ATTR_FILE, "vtypeprobe", id.c_str(), ok);
00933 if (!ok) {
00934 return;
00935 }
00936 try {
00937 myDetectorBuilder.buildVTypeProbe(id, type, frequency, OutputDevice::getDevice(file, getFileName()));
00938 } catch (InvalidArgument &e) {
00939 MsgHandler::getErrorInstance()->inform(e.what());
00940 } catch (IOError &e) {
00941 MsgHandler::getErrorInstance()->inform(e.what());
00942 }
00943 }
00944
00945
00946 void
00947 NLHandler::addRouteProbeDetector(const SUMOSAXAttributes &attrs) {
00948
00949 std::string id;
00950 if (!attrs.setIDFromAttributes("routeprobe", id)) {
00951 return;
00952 }
00953 bool ok = true;
00954 SUMOTime frequency = attrs.getSUMOTimeReporting(SUMO_ATTR_FREQUENCY, "routeprobe", id.c_str(), ok);
00955 SUMOTime begin = attrs.getOptSUMOTimeReporting(SUMO_ATTR_BEGIN, "routeprobe", id.c_str(), ok, -1);
00956 std::string edge = attrs.getStringReporting(SUMO_ATTR_EDGE, "routeprobe", id.c_str(), ok);
00957 std::string file = attrs.getStringReporting(SUMO_ATTR_FILE, "routeprobe", id.c_str(), ok);
00958 if (!ok) {
00959 return;
00960 }
00961 try {
00962 myDetectorBuilder.buildRouteProbe(id, edge, frequency, begin,
00963 OutputDevice::getDevice(file, getFileName()));
00964 } catch (InvalidArgument &e) {
00965 MsgHandler::getErrorInstance()->inform(e.what());
00966 } catch (IOError &e) {
00967 MsgHandler::getErrorInstance()->inform(e.what());
00968 }
00969 }
00970
00971
00972
00973 void
00974 NLHandler::addE2Detector(const SUMOSAXAttributes &attrs) {
00975
00976 std::string id;
00977 if (!attrs.setIDFromAttributes("e2-detector", id)) {
00978 return;
00979 }
00980
00981 bool ok = true;
00982 std::string lsaid = attrs.getOptStringReporting(SUMO_ATTR_TLID, "e2-detector", id.c_str(), ok, "<invalid>");
00983 std::string toLane = attrs.getOptStringReporting(SUMO_ATTR_TO, "e2-detector", id.c_str(), ok, "<invalid>");
00984
00985 if (attrs.getOptStringReporting(SUMO_ATTR_MEASURES, "e2-detector", id.c_str(), ok, "<invalid>")!="<invalid>") {
00986 MsgHandler::getWarningInstance()->inform("While parsing E2-detector '" + id + "': 'measures' is deprecated.");
00987 }
00988 if (attrs.getOptStringReporting(SUMO_ATTR_STYLE, "e2-detector", id.c_str(), ok, "<invalid>")!="<invalid>") {
00989 MsgHandler::getWarningInstance()->inform("While parsing E2-detector '" + id + "': 'style' is deprecated.");
00990 }
00991
00992 try {
00993 const SUMOTime haltingTimeThreshold = attrs.getOptSUMOTimeReporting(SUMO_ATTR_HALTING_TIME_THRESHOLD, "e2-detector", id.c_str(), ok, TIME2STEPS(1));
00994 const SUMOReal haltingSpeedThreshold = attrs.getOptSUMORealReporting(SUMO_ATTR_HALTING_SPEED_THRESHOLD, "e2-detector", id.c_str(), ok, 5.0f/3.6f);
00995 const SUMOReal jamDistThreshold = attrs.getOptSUMORealReporting(SUMO_ATTR_JAM_DIST_THRESHOLD, "e2-detector", id.c_str(), ok, 10.0f);
00996 const SUMOReal position = attrs.getSUMORealReporting(SUMO_ATTR_POSITION, "e2-detector", id.c_str(), ok);
00997 const SUMOReal length = attrs.getSUMORealReporting(SUMO_ATTR_LENGTH, "e2-detector", id.c_str(), ok);
00998 const bool friendlyPos = attrs.getOptBoolReporting(SUMO_ATTR_FRIENDLY_POS, "e2-detector", id.c_str(), ok, false);
00999 const bool cont = attrs.getOptBoolReporting(SUMO_ATTR_CONT, "e2-detector", id.c_str(), ok, false);
01000 const std::string lane = attrs.getStringReporting(SUMO_ATTR_LANE, "e2-detector", id.c_str(), ok);
01001 const std::string file = attrs.getStringReporting(SUMO_ATTR_FILE, "e2-detector", id.c_str(), ok);
01002 if (!ok) {
01003 return;
01004 }
01005 if (lsaid!="<invalid>") {
01006 if (toLane=="<invalid>") {
01007 myDetectorBuilder.buildE2Detector(id, lane, position, length, cont,
01008 myJunctionControlBuilder.getTLLogic(lsaid),
01009 OutputDevice::getDevice(file, getFileName()),
01010 (SUMOTime) haltingSpeedThreshold, haltingSpeedThreshold, jamDistThreshold,
01011 friendlyPos);
01012 } else {
01013 myDetectorBuilder.buildE2Detector(id, lane, position, length, cont,
01014 myJunctionControlBuilder.getTLLogic(lsaid), toLane,
01015 OutputDevice::getDevice(file, getFileName()),
01016 (SUMOTime) haltingSpeedThreshold, haltingSpeedThreshold, jamDistThreshold,
01017 friendlyPos);
01018 }
01019 } else {
01020 bool ok = true;
01021 SUMOTime frequency = attrs.getSUMOTimeReporting(SUMO_ATTR_FREQUENCY, "e2-detector", id.c_str(), ok);
01022 if (!ok) {
01023 return;
01024 }
01025 myDetectorBuilder.buildE2Detector(id, lane, position, length, cont, frequency,
01026 OutputDevice::getDevice(file, getFileName()),
01027 (SUMOTime) haltingSpeedThreshold, haltingSpeedThreshold, jamDistThreshold,
01028 friendlyPos);
01029 }
01030 } catch (InvalidArgument &e) {
01031 MsgHandler::getErrorInstance()->inform(e.what());
01032 } catch (IOError &e) {
01033 MsgHandler::getErrorInstance()->inform(e.what());
01034 }
01035 }
01036
01037
01038 void
01039 NLHandler::beginE3Detector(const SUMOSAXAttributes &attrs) {
01040
01041 std::string id;
01042 if (!attrs.setIDFromAttributes("e3-detector", id)) {
01043 return;
01044 }
01045 bool ok = true;
01046
01047 if (attrs.getOptStringReporting(SUMO_ATTR_MEASURES, "e3-detector", id.c_str(), ok, "<invalid>")!="<invalid>") {
01048 MsgHandler::getWarningInstance()->inform("While parsing E3-detector '" + id + "': 'measures' is deprecated.");
01049 }
01050 if (attrs.getOptStringReporting(SUMO_ATTR_STYLE, "e3-detector", id.c_str(), ok, "<invalid>")!="<invalid>") {
01051 MsgHandler::getWarningInstance()->inform("While parsing E3-detector '" + id + "': 'style' is deprecated.");
01052 }
01053 const SUMOTime frequency = attrs.getSUMOTimeReporting(SUMO_ATTR_FREQUENCY, "e3-detector", id.c_str(), ok);
01054 const SUMOTime haltingTimeThreshold = attrs.getOptSUMOTimeReporting(SUMO_ATTR_HALTING_TIME_THRESHOLD, "e3-detector", id.c_str(), ok, TIME2STEPS(1));
01055 const SUMOReal haltingSpeedThreshold = attrs.getOptSUMORealReporting(SUMO_ATTR_HALTING_SPEED_THRESHOLD, "e3-detector", id.c_str(), ok, 5.0f/3.6f);
01056 const std::string file = attrs.getStringReporting(SUMO_ATTR_FILE, "e3-detector", id.c_str(), ok);
01057 if (!ok) {
01058 return;
01059 }
01060 try {
01061 myDetectorBuilder.beginE3Detector(id,
01062 OutputDevice::getDevice(file, getFileName()),
01063 frequency, haltingSpeedThreshold, haltingTimeThreshold);
01064 } catch (InvalidArgument &e) {
01065 MsgHandler::getErrorInstance()->inform(e.what());
01066 } catch (IOError &e) {
01067 MsgHandler::getErrorInstance()->inform(e.what());
01068 }
01069 }
01070
01071
01072 void
01073 NLHandler::addE3Entry(const SUMOSAXAttributes &attrs) {
01074 bool ok = true;
01075 const SUMOReal position = attrs.getSUMORealReporting(SUMO_ATTR_POSITION, "e3-detector/entry", myDetectorBuilder.getCurrentE3ID().c_str(), ok);
01076 const bool friendlyPos = attrs.getOptBoolReporting(SUMO_ATTR_FRIENDLY_POS, "e3-detector/entry", myDetectorBuilder.getCurrentE3ID().c_str(), ok, false);
01077 const std::string lane = attrs.getStringReporting(SUMO_ATTR_LANE, "e3-detector/entry", myDetectorBuilder.getCurrentE3ID().c_str(), ok);
01078 if (!ok) {
01079 return;
01080 }
01081 myDetectorBuilder.addE3Entry(lane, position, friendlyPos);
01082 }
01083
01084
01085 void
01086 NLHandler::addE3Exit(const SUMOSAXAttributes &attrs) {
01087 bool ok = true;
01088 const SUMOReal position = attrs.getSUMORealReporting(SUMO_ATTR_POSITION, "e3-detector/exit", myDetectorBuilder.getCurrentE3ID().c_str(), ok);
01089 const bool friendlyPos = attrs.getOptBoolReporting(SUMO_ATTR_FRIENDLY_POS, "e3-detector/exit", myDetectorBuilder.getCurrentE3ID().c_str(), ok, false);
01090 const std::string lane = attrs.getStringReporting(SUMO_ATTR_LANE, "e3-detector/exit", myDetectorBuilder.getCurrentE3ID().c_str(), ok);
01091 if (!ok) {
01092 return;
01093 }
01094 myDetectorBuilder.addE3Exit(lane, position, friendlyPos);
01095 }
01096
01097
01098 void
01099 NLHandler::addEdgeLaneMeanData(const SUMOSAXAttributes &attrs, const char* objecttype) {
01100
01101 std::string id;
01102 if (!attrs.setIDFromAttributes(objecttype, id)) {
01103 return;
01104 }
01105 bool ok = true;
01106 const SUMOReal maxTravelTime = attrs.getOptSUMORealReporting(SUMO_ATTR_MAX_TRAVELTIME, objecttype, id.c_str(), ok, 100000);
01107 const SUMOReal minSamples = attrs.getOptSUMORealReporting(SUMO_ATTR_MIN_SAMPLES, objecttype, id.c_str(), ok, 0);
01108 const SUMOReal haltingSpeedThreshold = attrs.getOptSUMORealReporting(SUMO_ATTR_HALTING_SPEED_THRESHOLD, objecttype, id.c_str(), ok, POSITION_EPS);
01109 const bool excludeEmpty = attrs.getOptBoolReporting(SUMO_ATTR_EXCLUDE_EMPTY, objecttype, id.c_str(), ok, false);
01110 const bool withInternal = attrs.getOptBoolReporting(SUMO_ATTR_WITH_INTERNAL, objecttype, id.c_str(), ok, false);
01111 const bool trackVehicles = attrs.getOptBoolReporting(SUMO_ATTR_TRACK_VEHICLES, objecttype, id.c_str(), ok, false);
01112 const std::string file = attrs.getStringReporting(SUMO_ATTR_FILE, objecttype, id.c_str(), ok);
01113 const std::string type = attrs.getOptStringReporting(SUMO_ATTR_TYPE, objecttype, id.c_str(), ok, "performance");
01114 const std::string vtypes = attrs.getOptStringReporting(SUMO_ATTR_VTYPES, objecttype, id.c_str(), ok, "");
01115 const SUMOTime frequency = attrs.getOptSUMOTimeReporting(SUMO_ATTR_FREQUENCY, objecttype, id.c_str(), ok, -1);
01116 const SUMOTime begin = attrs.getOptSUMOTimeReporting(SUMO_ATTR_BEGIN, objecttype, id.c_str(), ok, string2time(OptionsCont::getOptions().getString("begin")));
01117 const SUMOTime end = attrs.getOptSUMOTimeReporting(SUMO_ATTR_END, objecttype, id.c_str(), ok, string2time(OptionsCont::getOptions().getString("end")));
01118 if (!ok) {
01119 return;
01120 }
01121 try {
01122 myDetectorBuilder.createEdgeLaneMeanData(id, frequency, begin, end,
01123 type, objecttype=="meandata_lane", !excludeEmpty, withInternal, trackVehicles,
01124 maxTravelTime, minSamples, haltingSpeedThreshold, vtypes,
01125 OutputDevice::getDevice(file, getFileName()));
01126 } catch (InvalidArgument &e) {
01127 MsgHandler::getErrorInstance()->inform(e.what());
01128 } catch (IOError &e) {
01129 MsgHandler::getErrorInstance()->inform(e.what());
01130 }
01131 }
01132
01133
01134
01135 void
01136 NLHandler::addSource(const SUMOSAXAttributes &attrs) {
01137
01138 std::string id;
01139 if (!attrs.setIDFromAttributes("source", id)) {
01140 return;
01141 }
01142 try {
01143 myTriggerBuilder.buildTrigger(myNet, attrs, getFileName());
01144 } catch (InvalidArgument &e) {
01145 MsgHandler::getErrorInstance()->inform(e.what());
01146 }
01147 }
01148
01149
01150 void
01151 NLHandler::addTrigger(const SUMOSAXAttributes &attrs) {
01152
01153 std::string id;
01154 if (!attrs.setIDFromAttributes("trigger", id)) {
01155 return;
01156 }
01157 try {
01158 myTriggerBuilder.buildTrigger(myNet, attrs, getFileName());
01159 return;
01160 } catch (InvalidArgument &e) {
01161 MsgHandler::getErrorInstance()->inform(e.what());
01162 }
01163 }
01164
01165
01166 void
01167 NLHandler::openSucc(const SUMOSAXAttributes &attrs) {
01168 bool ok = true;
01169 std::string id = attrs.getStringReporting(SUMO_ATTR_LANE, "succ", 0, ok);
01170 if (!MSGlobals::gUsingInternalLanes&&id[0]==':') {
01171 myCurrentIsInternalToSkip = true;
01172 return;
01173 }
01174 myCurrentIsInternalToSkip = false;
01175 mySucceedingLaneBuilder.openSuccLane(id);
01176 }
01177
01178
01179 void
01180 NLHandler::addSuccLane(const SUMOSAXAttributes &attrs) {
01181
01182 if (myCurrentIsInternalToSkip) {
01183 return;
01184 }
01185 try {
01186 bool ok = true;
01187 SUMOReal pass = attrs.getOptSUMORealReporting(SUMO_ATTR_PASS, 0, 0, ok, -1);
01188 bool yield = attrs.getBoolReporting(SUMO_ATTR_YIELD, 0, 0, ok);
01189 bool internalEnd = attrs.getOptBoolReporting(SUMO_ATTR_YIELD, 0, 0, ok, false);
01190 std::string lane = attrs.getStringReporting(SUMO_ATTR_LANE, 0, 0, ok);
01191 std::string dir = attrs.getStringReporting(SUMO_ATTR_DIR, 0, 0, ok);
01192 std::string state = attrs.getStringReporting(SUMO_ATTR_STATE, 0, 0, ok);
01193 std::string tlID = attrs.getOptStringReporting(SUMO_ATTR_TLID, 0, 0, ok, "");
01194 #ifdef HAVE_INTERNAL_LANES
01195 std::string via = attrs.getOptStringReporting(SUMO_ATTR_VIA, 0, 0, ok, "");
01196 #endif
01197 if (!ok) {
01198 return;
01199 }
01200 if (tlID!="") {
01201 int linkNumber = attrs.getIntReporting(SUMO_ATTR_TLLINKNO, 0, 0, ok);
01202 if (!ok) {
01203 return;
01204 }
01205 mySucceedingLaneBuilder.addSuccLane(yield, lane,
01206 #ifdef HAVE_INTERNAL_LANES
01207 via, pass,
01208 #endif
01209 parseLinkDir(dir[0]), parseLinkState(state[0]), internalEnd, tlID, linkNumber);
01210 } else {
01211 mySucceedingLaneBuilder.addSuccLane(yield, lane,
01212 #ifdef HAVE_INTERNAL_LANES
01213 via, pass,
01214 #endif
01215 parseLinkDir(dir[0]), parseLinkState(state[0]), internalEnd);
01216 }
01217 } catch (InvalidArgument &e) {
01218 MsgHandler::getErrorInstance()->inform(e.what());
01219 }
01220 }
01221
01222
01223
01224 MSLink::LinkDirection
01225 NLHandler::parseLinkDir(char dir) {
01226 switch (dir) {
01227 case 's':
01228 return MSLink::LINKDIR_STRAIGHT;
01229 case 'l':
01230 return MSLink::LINKDIR_LEFT;
01231 case 'r':
01232 return MSLink::LINKDIR_RIGHT;
01233 case 't':
01234 return MSLink::LINKDIR_TURN;
01235 case 'L':
01236 return MSLink::LINKDIR_PARTLEFT;
01237 case 'R':
01238 return MSLink::LINKDIR_PARTRIGHT;
01239 default:
01240 throw InvalidArgument("Unrecognised link direction '" + toString(dir) + "'.");
01241 }
01242 }
01243
01244
01245 MSLink::LinkState
01246 NLHandler::parseLinkState(char state) {
01247 switch (state) {
01248 case 't':
01249 case 'o':
01250 return MSLink::LINKSTATE_TL_OFF_BLINKING;
01251 case 'O':
01252 return MSLink::LINKSTATE_TL_OFF_NOSIGNAL;
01253 case 'M':
01254 return MSLink::LINKSTATE_MAJOR;
01255 case 'm':
01256 return MSLink::LINKSTATE_MINOR;
01257 case '=':
01258 return MSLink::LINKSTATE_EQUAL;
01259 default:
01260 throw InvalidArgument("Unrecognised link state '" + toString(state) + "'.");
01261 }
01262 }
01263
01264
01265
01266
01267 void
01268 NLHandler::setRequestSize(const std::string &chars) {
01269
01270 try {
01271 myJunctionControlBuilder.setRequestSize(TplConvert<char>::_2int(chars.c_str()));
01272 } catch (EmptyData &) {
01273 MsgHandler::getErrorInstance()->inform("Missing request size.");
01274 } catch (NumberFormatException &) {
01275 MsgHandler::getErrorInstance()->inform("One of an edge's SUMOSAXAttributes must be numeric but is not.");
01276 }
01277 }
01278
01279
01280 void
01281 NLHandler::setLaneNumber(const std::string &chars) {
01282
01283 try {
01284 myJunctionControlBuilder.setLaneNumber(TplConvert<char>::_2int(chars.c_str()));
01285 } catch (EmptyData &) {
01286 MsgHandler::getErrorInstance()->inform("Missing lane number.");
01287 } catch (NumberFormatException &) {
01288 MsgHandler::getErrorInstance()->inform("One of an edge's SUMOSAXAttributes must be numeric but is not.");
01289 }
01290 }
01291
01292
01293 void
01294 NLHandler::setKey(const std::string &chars) {
01295
01296 if (chars.length()==0) {
01297 MsgHandler::getErrorInstance()->inform("No key given for the current junction logic.");
01298 return;
01299 }
01300 myJunctionControlBuilder.setKey(chars);
01301 }
01302
01303
01304 void
01305 NLHandler::setSubKey(const std::string &chars) {
01306
01307 if (chars.length()==0) {
01308 MsgHandler::getErrorInstance()->inform("No subkey given for the current junction logic.");
01309 return;
01310 }
01311 myJunctionControlBuilder.setSubKey(chars);
01312 }
01313
01314
01315 void
01316 NLHandler::setOffset(const std::string &chars) {
01317
01318 try {
01319 myJunctionControlBuilder.setOffset(string2time(chars));
01320 } catch (NumberFormatException &) {
01321 MsgHandler::getErrorInstance()->inform("The offset for a junction is not numeric.");
01322 } catch (EmptyData &) {
01323 MsgHandler::getErrorInstance()->inform("The offset for a junction is not empty.");
01324 }
01325 }
01326
01327
01328 void
01329 NLHandler::addJunctionShape(const std::string &chars) {
01330
01331 if (!myHaveWarnedAboutDeprecatedJunctionShape) {
01332 myHaveWarnedAboutDeprecatedJunctionShape = true;
01333 MsgHandler::getWarningInstance()->inform("Your network uses a deprecated junction shape description; please rebuild.");
01334 }
01335 bool ok = true;
01336 Position2DVector shape = GeomConvHelper::parseShapeReporting(chars, "junction", myJunctionControlBuilder.getActiveID().c_str(), ok, true);
01337 if (ok) {
01338 myJunctionControlBuilder.addJunctionShape(shape);
01339 }
01340 }
01341
01342
01343 void
01344 NLHandler::setLocation(const SUMOSAXAttributes &attrs) {
01345 bool ok = true;
01346 Position2DVector s = GeomConvHelper::parseShapeReporting(attrs.getStringReporting(SUMO_ATTR_NET_OFFSET, "net", 0, ok), "net", 0, ok, false);
01347 Boundary convBoundary = GeomConvHelper::parseBoundaryReporting(attrs.getStringReporting(SUMO_ATTR_CONV_BOUNDARY, "net", 0, ok), "net", 0, ok);
01348 Boundary origBoundary = GeomConvHelper::parseBoundaryReporting(attrs.getStringReporting(SUMO_ATTR_ORIG_BOUNDARY, "net", 0, ok), "net", 0, ok);
01349 std::string proj = attrs.getStringReporting(SUMO_ATTR_ORIG_PROJ, "net", 0, ok);
01350 if (ok) {
01351 Position2D networkOffset = s[0];
01352 GeoConvHelper::init(proj, networkOffset, origBoundary, convBoundary);
01353 }
01354 }
01355
01356
01357 void
01358 NLHandler::addDistrict(const SUMOSAXAttributes &attrs) throw(ProcessError) {
01359 myCurrentIsBroken = false;
01360
01361 if (!attrs.setIDFromAttributes("district", myCurrentDistrictID)) {
01362 myCurrentIsBroken = true;
01363 return;
01364 }
01365 try {
01366 MSEdge* sink = myEdgeControlBuilder.buildEdge(myCurrentDistrictID);
01367 if (!MSEdge::dictionary(myCurrentDistrictID, sink)) {
01368 delete sink;
01369 throw InvalidArgument("Another edge with the id '" + myCurrentDistrictID + "' exists.");
01370 }
01371 sink->initialize(0, 0, MSEdge::EDGEFUNCTION_DISTRICT);
01372 MSEdge* source = myEdgeControlBuilder.buildEdge(myCurrentDistrictID + "-source");
01373 if (!MSEdge::dictionary(myCurrentDistrictID + "-source", source)) {
01374 delete source;
01375 throw InvalidArgument("Another edge with the id '" + myCurrentDistrictID + "-source' exists.");
01376 }
01377 source->initialize(0, 0, MSEdge::EDGEFUNCTION_DISTRICT);
01378 if (attrs.hasAttribute(SUMO_ATTR_EDGES)) {
01379 std::vector<std::string> desc = StringTokenizer(attrs.getString(SUMO_ATTR_EDGES)).getVector();
01380 for (std::vector<std::string>::const_iterator i=desc.begin(); i!=desc.end(); ++i) {
01381 MSEdge *edge = MSEdge::dictionary(*i);
01382
01383 if (edge==0) {
01384 throw InvalidArgument("The edge '" + *i + "' within district '" + myCurrentDistrictID + "' is not known.");
01385 }
01386 source->addFollower(edge);
01387 edge->addFollower(sink);
01388 }
01389 }
01390 } catch (InvalidArgument &e) {
01391 MsgHandler::getErrorInstance()->inform(e.what());
01392 myCurrentIsBroken = true;
01393 }
01394 }
01395
01396
01397 void
01398 NLHandler::addDistrictEdge(const SUMOSAXAttributes &attrs, bool isSource) {
01399 if (myCurrentIsBroken) {
01400
01401 return;
01402 }
01403 bool ok = true;
01404 std::string id = attrs.getStringReporting(SUMO_ATTR_ID, "district", myCurrentDistrictID.c_str(), ok);
01405 MSEdge *succ = MSEdge::dictionary(id);
01406 if (succ!=0) {
01407
01408 if (isSource) {
01409 MSEdge::dictionary(myCurrentDistrictID + "-source")->addFollower(succ);
01410 } else {
01411 succ->addFollower(MSEdge::dictionary(myCurrentDistrictID));
01412 }
01413 } else {
01414 MsgHandler::getErrorInstance()->inform("At district '" + myCurrentDistrictID + "': succeeding edge '" + id + "' does not exist.");
01415 }
01416 }
01417
01418
01419
01420
01421 void
01422 NLHandler::addIncomingLanes(const std::string &chars) {
01423
01424 StringTokenizer st(chars);
01425 while (st.hasNext()) {
01426 std::string set = st.next();
01427 MSLane *lane = MSLane::dictionary(set);
01428 if (!MSGlobals::gUsingInternalLanes&&set[0]==':') {
01429 continue;
01430 }
01431 if (lane==0) {
01432 MsgHandler::getErrorInstance()->inform("An unknown lane ('" + set + "') was tried to be set as incoming to junction '" + myJunctionControlBuilder.getActiveID() + "'.");
01433 return;
01434 }
01435 myJunctionControlBuilder.addIncomingLane(lane);
01436 }
01437 }
01438
01439
01440 #ifdef HAVE_INTERNAL_LANES
01441 void
01442 NLHandler::addInternalLanes(const std::string &chars) {
01443
01444
01445 if (!MSGlobals::gUsingInternalLanes) {
01446 return;
01447 }
01448 StringTokenizer st(chars);
01449 while (st.hasNext()) {
01450 std::string set = st.next();
01451 MSLane *lane = MSLane::dictionary(set);
01452 if (lane==0) {
01453 MsgHandler::getErrorInstance()->inform("An unknown lane ('" + set + "') was tried to be set as internal.");
01454 return;
01455 }
01456 myJunctionControlBuilder.addInternalLane(lane);
01457 }
01458 }
01459 #endif
01460
01461
01462
01463
01464
01465
01466
01467
01468
01469 void
01470 NLHandler::closeSuccLane() {
01471
01472 if (myCurrentIsInternalToSkip) {
01473 return;
01474 }
01475 try {
01476 mySucceedingLaneBuilder.closeSuccLane();
01477 } catch (InvalidArgument &e) {
01478 MsgHandler::getErrorInstance()->inform(e.what());
01479 }
01480 }
01481
01482
01483 void
01484 NLHandler::endDetector() {
01485 if (myCurrentDetectorType=="e3") {
01486 endE3Detector();
01487 }
01488 myCurrentDetectorType = "";
01489 }
01490
01491
01492 void
01493 NLHandler::endE3Detector() {
01494 try {
01495 myDetectorBuilder.endE3Detector();
01496 } catch (InvalidArgument &e) {
01497 MsgHandler::getErrorInstance()->inform(e.what());
01498 }
01499 }
01500
01501
01502 void
01503 NLHandler::closeWAUT() {
01504 if (!myCurrentIsBroken) {
01505 try {
01506 myJunctionControlBuilder.getTLLogicControlToUse().closeWAUT(myCurrentWAUTID);
01507 } catch (InvalidArgument &e) {
01508 MsgHandler::getErrorInstance()->inform(e.what());
01509 myCurrentIsBroken = true;
01510 }
01511 }
01512 myCurrentWAUTID = "";
01513 }
01514
01515
01516