SUMO - Simulation of Urban MObility
NLHandler.cpp
Go to the documentation of this file.
00001 /****************************************************************************/
00012 // The XML-Handler for network loading
00013 /****************************************************************************/
00014 // SUMO, Simulation of Urban MObility; see http://sumo.sourceforge.net/
00015 // Copyright (C) 2001-2012 DLR (http://www.dlr.de/) and contributors
00016 /****************************************************************************/
00017 //
00018 //   This file is part of SUMO.
00019 //   SUMO is free software: you can redistribute it and/or modify
00020 //   it under the terms of the GNU General Public License as published by
00021 //   the Free Software Foundation, either version 3 of the License, or
00022 //   (at your option) any later version.
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 "NLHandler.h"
00036 #include "NLEdgeControlBuilder.h"
00037 #include "NLJunctionControlBuilder.h"
00038 #include "NLDetectorBuilder.h"
00039 #include "NLTriggerBuilder.h"
00040 #include <utils/xml/SUMOXMLDefinitions.h>
00041 #include <utils/xml/SUMOSAXHandler.h>
00042 #include <utils/common/MsgHandler.h>
00043 #include <utils/common/SUMOTime.h>
00044 #include <utils/common/TplConvert.h>
00045 #include <utils/common/TplConvertSec.h>
00046 #include <utils/common/StringTokenizer.h>
00047 #include <utils/common/RGBColor.h>
00048 #include <utils/geom/GeomConvHelper.h>
00049 #include <microsim/MSGlobals.h>
00050 #include <microsim/MSLane.h>
00051 #include <microsim/MSInternalLane.h>
00052 #include <microsim/MSBitSetLogic.h>
00053 #include <microsim/MSJunctionLogic.h>
00054 #include <microsim/traffic_lights/MSTrafficLightLogic.h>
00055 #include <microsim/traffic_lights/MSAgentbasedTrafficLightLogic.h>
00056 #include <utils/iodevices/OutputDevice.h>
00057 #include <utils/common/UtilExceptions.h>
00058 #include <utils/geom/GeoConvHelper.h>
00059 #include <utils/shapes/ShapeContainer.h>
00060 #include <utils/gui/globjects/GUIGlObject.h>
00061 
00062 #ifdef CHECK_MEMORY_LEAKS
00063 #include <foreign/nvwa/debug_new.h>
00064 #endif // CHECK_MEMORY_LEAKS
00065 
00066 
00067 // ===========================================================================
00068 // method definitions
00069 // ===========================================================================
00070 NLHandler::NLHandler(const std::string& file, MSNet& net,
00071                      NLDetectorBuilder& detBuilder,
00072                      NLTriggerBuilder& triggerBuilder,
00073                      NLEdgeControlBuilder& edgeBuilder,
00074                      NLJunctionControlBuilder& junctionBuilder)
00075     : MSRouteHandler(file, true),
00076       myNet(net), myActionBuilder(net),
00077       myCurrentIsInternalToSkip(false),
00078       myDetectorBuilder(detBuilder), myTriggerBuilder(triggerBuilder),
00079       myEdgeControlBuilder(edgeBuilder), myJunctionControlBuilder(junctionBuilder),
00080       mySucceedingLaneBuilder(junctionBuilder),
00081       myAmInTLLogicMode(false), myCurrentIsBroken(false),
00082       myHaveWarnedAboutDeprecatedE1(false),
00083       myHaveWarnedAboutDeprecatedE2(false),
00084       myHaveWarnedAboutDeprecatedE3(false),
00085       myHaveWarnedAboutDeprecatedDetEntry(false),
00086       myHaveWarnedAboutDeprecatedDetExit(false),
00087       myHaveWarnedAboutDeprecatedRowLogic(false),
00088       myHaveWarnedAboutDeprecatedTLLogic(false),
00089       myHaveWarnedAboutDeprecatedTimedEvent(false),
00090       myHaveWarnedAboutDeprecatedTLSTiming(false),
00091       myHaveWarnedAboutDeprecatedTimeThreshold(false),
00092       myHaveWarnedAboutDeprecatedSpeedThreshold(false),
00093       myHaveWarnedAboutDeprecatedJamDistThreshold(false),
00094       myHaveWarnedAboutDeprecatedVTypeProbe(false),
00095       myHaveWarnedAboutDeprecatedRouteProbe(false),
00096       myHaveWarnedAboutDeprecatedEdgeMean(false),
00097       myHaveWarnedAboutDeprecatedLaneMean(false),
00098       myHaveWarnedAboutDeprecatedVTypes(false),
00099       myHaveWarnedAboutDeprecatedLanes(false),
00100       myHaveWarnedAboutDeprecatedDistrict(false), myHaveWarnedAboutDeprecatedDSource(false), myHaveWarnedAboutDeprecatedDSink(false) {}
00101 
00102 
00103 NLHandler::~NLHandler() {}
00104 
00105 
00106 void
00107 NLHandler::myStartElement(int element,
00108                           const SUMOSAXAttributes& attrs) {
00109     try {
00110         switch (element) {
00111             case SUMO_TAG_EDGE:
00112                 beginEdgeParsing(attrs);
00113                 break;
00114             case SUMO_TAG_LANE:
00115                 addLane(attrs);
00116                 break;
00117             case SUMO_TAG_POLY:
00118                 addPoly(attrs);
00119                 break;
00120             case SUMO_TAG_POI:
00121                 addPOI(attrs);
00122                 break;
00123             case SUMO_TAG_JUNCTION:
00124                 openJunction(attrs);
00125                 initJunctionLogic(attrs);
00126                 break;
00127             case SUMO_TAG_PHASE:
00128                 addPhase(attrs);
00129                 break;
00130             case SUMO_TAG_SUCC:
00131                 openSucc(attrs);
00132                 break;
00133             case SUMO_TAG_SUCCLANE:
00134                 addSuccLane(attrs);
00135                 break;
00136             case SUMO_TAG_CONNECTION:
00137                 addConnection(attrs);
00138                 break;
00139             case SUMO_TAG_ROWLOGIC__DEPRECATED:
00140                 if (!myHaveWarnedAboutDeprecatedRowLogic) {
00141                     myHaveWarnedAboutDeprecatedRowLogic = true;
00142                     WRITE_WARNING("Your network uses deprecated tags; please rebuild.");
00143                 }
00144                 initJunctionLogic(attrs);
00145                 break;
00146             case SUMO_TAG_TLLOGIC__DEPRECATED:
00147                 if (!myHaveWarnedAboutDeprecatedTLLogic) {
00148                     myHaveWarnedAboutDeprecatedTLLogic = true;
00149                     WRITE_WARNING("Deprecated tl-logic name; please rebuild.");
00150                 }
00151             case SUMO_TAG_TLLOGIC:
00152                 initTrafficLightLogic(attrs);
00153                 break;
00154             case SUMO_TAG_LOGICITEM: // deprecated
00155                 addLogicItem(attrs);
00156                 break;
00157             case SUMO_TAG_REQUEST:
00158                 addRequest(attrs);
00159                 break;
00160             case SUMO_TAG_WAUT:
00161                 openWAUT(attrs);
00162                 break;
00163             case SUMO_TAG_WAUT_SWITCH:
00164                 addWAUTSwitch(attrs);
00165                 break;
00166             case SUMO_TAG_WAUT_JUNCTION:
00167                 addWAUTJunction(attrs);
00168                 break;
00169 #ifdef _MESSAGES
00170             case SUMO_TAG_MSG_EMITTER:
00171                 addMsgEmitter(attrs);
00172                 break;
00173 #endif
00174             case SUMO_TAG_E1DETECTOR__DEPRECATED:
00175                 if (!myHaveWarnedAboutDeprecatedE1) {
00176                     myHaveWarnedAboutDeprecatedE1 = true;
00177                     WRITE_WARNING("'" + toString(SUMO_TAG_E1DETECTOR__DEPRECATED) + "' is deprecated; please use '" + toString(SUMO_TAG_E1DETECTOR) + "'.");
00178                 }
00179             case SUMO_TAG_E1DETECTOR:
00180             case SUMO_TAG_INDUCTION_LOOP:
00181                 addE1Detector(attrs);
00182                 break;
00183             case SUMO_TAG_E2DETECTOR__DEPRECATED:
00184                 if (!myHaveWarnedAboutDeprecatedE2) {
00185                     myHaveWarnedAboutDeprecatedE2 = true;
00186                     WRITE_WARNING("'" + toString(SUMO_TAG_E2DETECTOR__DEPRECATED) + "' is deprecated; please use '" + toString(SUMO_TAG_E2DETECTOR) + "'.");
00187                 }
00188             case SUMO_TAG_E2DETECTOR:
00189             case SUMO_TAG_LANE_AREA_DETECTOR:
00190                 addE2Detector(attrs);
00191                 break;
00192             case SUMO_TAG_E3DETECTOR__DEPRECATED:
00193                 if (!myHaveWarnedAboutDeprecatedE3) {
00194                     myHaveWarnedAboutDeprecatedE3 = true;
00195                     WRITE_WARNING("'" + toString(SUMO_TAG_E3DETECTOR__DEPRECATED) + "' is deprecated; please use '" + toString(SUMO_TAG_E3DETECTOR) + "'.");
00196                 }
00197             case SUMO_TAG_E3DETECTOR:
00198             case SUMO_TAG_ENTRY_EXIT_DETECTOR:
00199                 beginE3Detector(attrs);
00200                 break;
00201             case SUMO_TAG_DET_ENTRY__DEPRECATED:
00202                 if (!myHaveWarnedAboutDeprecatedDetEntry) {
00203                     myHaveWarnedAboutDeprecatedDetEntry = true;
00204                     WRITE_WARNING("'" + toString(SUMO_TAG_DET_ENTRY__DEPRECATED) + "' is deprecated; please use '" + toString(SUMO_TAG_DET_ENTRY) + "'.");
00205                 }
00206             case SUMO_TAG_DET_ENTRY:
00207                 addE3Entry(attrs);
00208                 break;
00209             case SUMO_TAG_DET_EXIT__DEPRECATED:
00210                 if (!myHaveWarnedAboutDeprecatedDetExit) {
00211                     myHaveWarnedAboutDeprecatedDetExit = true;
00212                     WRITE_WARNING("'" + toString(SUMO_TAG_DET_EXIT__DEPRECATED) + "' is deprecated; please use '" + toString(SUMO_TAG_DET_EXIT) + "'.");
00213                 }
00214             case SUMO_TAG_DET_EXIT:
00215                 addE3Exit(attrs);
00216                 break;
00217             case SUMO_TAG_INSTANT_INDUCTION_LOOP:
00218                 addInstantE1Detector(attrs);
00219                 break;
00220             case SUMO_TAG_VSS:
00221                 myTriggerBuilder.parseAndBuildLaneSpeedTrigger(myNet, attrs, getFileName());
00222                 break;
00223 #ifdef HAVE_MESOSIM
00224             case SUMO_TAG_CALIBRATOR:
00225                 myTriggerBuilder.parseAndBuildCalibrator(myNet, attrs, getFileName());
00226                 break;
00227 #endif
00228             case SUMO_TAG_REROUTER:
00229                 myTriggerBuilder.parseAndBuildRerouter(myNet, attrs, getFileName());
00230                 break;
00231             case SUMO_TAG_BUS_STOP:
00232                 myTriggerBuilder.parseAndBuildBusStop(myNet, attrs);
00233                 break;
00234             case SUMO_TAG_VTYPEPROBE__DEPRECATED:
00235                 if (!myHaveWarnedAboutDeprecatedVTypeProbe) {
00236                     myHaveWarnedAboutDeprecatedVTypeProbe = true;
00237                     WRITE_WARNING("'" + toString(SUMO_TAG_VTYPEPROBE__DEPRECATED) + "' is deprecated; please use '" + toString(SUMO_TAG_VTYPEPROBE) + "'.");
00238                 }
00239             case SUMO_TAG_VTYPEPROBE:
00240                 addVTypeProbeDetector(attrs);
00241                 break;
00242             case SUMO_TAG_ROUTEPROBE__DEPRECATED:
00243                 if (!myHaveWarnedAboutDeprecatedRouteProbe) {
00244                     myHaveWarnedAboutDeprecatedRouteProbe = true;
00245                     WRITE_WARNING("'" + toString(SUMO_TAG_ROUTEPROBE__DEPRECATED) + "' is deprecated; please use '" + toString(SUMO_TAG_ROUTEPROBE) + "'.");
00246                 }
00247             case SUMO_TAG_ROUTEPROBE:
00248                 addRouteProbeDetector(attrs);
00249                 break;
00250             case SUMO_TAG_MEANDATA_EDGE__DEPRECATED:
00251                 if (!myHaveWarnedAboutDeprecatedEdgeMean) {
00252                     myHaveWarnedAboutDeprecatedEdgeMean = true;
00253                     WRITE_WARNING("'" + toString(SUMO_TAG_MEANDATA_EDGE__DEPRECATED) + "' is deprecated; please use '" + toString(SUMO_TAG_MEANDATA_EDGE) + "'.");
00254                 }
00255             case SUMO_TAG_MEANDATA_EDGE:
00256                 addEdgeLaneMeanData(attrs, SUMO_TAG_MEANDATA_EDGE);
00257                 break;
00258             case SUMO_TAG_MEANDATA_LANE__DEPRECATED:
00259                 if (!myHaveWarnedAboutDeprecatedLaneMean) {
00260                     myHaveWarnedAboutDeprecatedLaneMean = true;
00261                     WRITE_WARNING("'" + toString(SUMO_TAG_MEANDATA_LANE__DEPRECATED) + "' is deprecated; please use '" + toString(SUMO_TAG_MEANDATA_LANE) + "'.");
00262                 }
00263             case SUMO_TAG_MEANDATA_LANE:
00264                 addEdgeLaneMeanData(attrs, SUMO_TAG_MEANDATA_LANE);
00265                 break;
00266             case SUMO_TAG_TIMEDEVENT__DEPRECATED:
00267                 if (!myHaveWarnedAboutDeprecatedTimedEvent) {
00268                     myHaveWarnedAboutDeprecatedTimedEvent = true;
00269                     WRITE_WARNING("'" + toString(SUMO_TAG_TIMEDEVENT__DEPRECATED) + "' is deprecated; please use '" + toString(SUMO_TAG_TIMEDEVENT) + "'.");
00270                 }
00271             case SUMO_TAG_TIMEDEVENT:
00272                 myActionBuilder.addAction(attrs, getFileName());
00273                 break;
00274             case SUMO_TAG_VAPORIZER:
00275                 myTriggerBuilder.buildVaporizer(attrs);
00276                 break;
00277             case SUMO_TAG_LOCATION:
00278                 setLocation(attrs);
00279                 break;
00280             case SUMO_TAG_DISTRICT__DEPRECATED:
00281                 if (!myHaveWarnedAboutDeprecatedDistrict) {
00282                     myHaveWarnedAboutDeprecatedDistrict = true;
00283                     WRITE_WARNING("'" + toString(SUMO_TAG_DISTRICT__DEPRECATED) + "' is deprecated, please use '" + toString(SUMO_TAG_TAZ) + "'.");
00284                 }
00285             case SUMO_TAG_TAZ:
00286                 addDistrict(attrs);
00287                 break;
00288             case SUMO_TAG_DSOURCE__DEPRECATED:
00289                 if (!myHaveWarnedAboutDeprecatedDSource) {
00290                     myHaveWarnedAboutDeprecatedDSource = true;
00291                     WRITE_WARNING("'" + toString(SUMO_TAG_DSOURCE__DEPRECATED) + "' is deprecated, please use '" + toString(SUMO_TAG_TAZSOURCE) + "'.");
00292                 }
00293             case SUMO_TAG_TAZSOURCE:
00294                 addDistrictEdge(attrs, true);
00295                 break;
00296             case SUMO_TAG_DSINK__DEPRECATED:
00297                 if (!myHaveWarnedAboutDeprecatedDSink) {
00298                     myHaveWarnedAboutDeprecatedDSink = true;
00299                     WRITE_WARNING("'" + toString(SUMO_TAG_DSINK__DEPRECATED) + "' is deprecated, please use '" + toString(SUMO_TAG_TAZSINK) + "'.");
00300                 }
00301             case SUMO_TAG_TAZSINK:
00302                 addDistrictEdge(attrs, false);
00303                 break;
00304             default:
00305                 break;
00306         }
00307     } catch (InvalidArgument& e) {
00308         WRITE_ERROR(e.what());
00309     }
00310     MSRouteHandler::myStartElement(element, attrs);
00311     if (element == SUMO_TAG_PARAM) {
00312         addParam(attrs);
00313     }
00314 }
00315 
00316 
00317 void
00318 NLHandler::myEndElement(int element) {
00319     switch (element) {
00320         case SUMO_TAG_EDGE:
00321             closeEdge();
00322             break;
00323         case SUMO_TAG_JUNCTION:
00324             if (!myCurrentIsBroken) {
00325                 try {
00326                     myJunctionControlBuilder.closeJunctionLogic();
00327                     myJunctionControlBuilder.closeJunction();
00328                 } catch (InvalidArgument& e) {
00329                     WRITE_ERROR(e.what());
00330                 }
00331             }
00332             break;
00333         case SUMO_TAG_SUCC:
00334             closeSuccLane();
00335             break;
00336         case SUMO_TAG_ROWLOGIC__DEPRECATED:
00337             try {
00338                 myJunctionControlBuilder.closeJunctionLogic();
00339             } catch (InvalidArgument& e) {
00340                 WRITE_ERROR(e.what());
00341             }
00342             break;
00343         case SUMO_TAG_TLLOGIC__DEPRECATED:
00344         case SUMO_TAG_TLLOGIC:
00345             try {
00346                 myJunctionControlBuilder.closeTrafficLightLogic();
00347             } catch (InvalidArgument& e) {
00348                 WRITE_ERROR(e.what());
00349             }
00350             myAmInTLLogicMode = false;
00351             break;
00352         case SUMO_TAG_WAUT:
00353             closeWAUT();
00354             break;
00355         case SUMO_TAG_E3DETECTOR__DEPRECATED:
00356         case SUMO_TAG_E3DETECTOR:
00357         case SUMO_TAG_ENTRY_EXIT_DETECTOR:
00358             endE3Detector();
00359             break;
00360         default:
00361             break;
00362     }
00363     MSRouteHandler::myEndElement(element);
00364 }
00365 
00366 
00367 
00368 // ---- the root/edge - element
00369 void
00370 NLHandler::beginEdgeParsing(const SUMOSAXAttributes& attrs) {
00371     bool ok = true;
00372     myCurrentIsBroken = false;
00373     // get the id, report an error if not given or empty...
00374     std::string id = attrs.getStringReporting(SUMO_ATTR_ID, 0, ok);
00375     if (!ok) {
00376         myCurrentIsBroken = true;
00377         return;
00378     }
00379     // omit internal edges if not wished
00380     if (!MSGlobals::gUsingInternalLanes && id[0] == ':') {
00381         myCurrentIsInternalToSkip = true;
00382         return;
00383     }
00384     myCurrentIsInternalToSkip = false;
00385     // parse the function
00386     SumoXMLEdgeFunc func = EDGEFUNC_NORMAL;
00387     std::string funcString = attrs.getOptStringReporting(SUMO_ATTR_FUNCTION, id.c_str(), ok, toString(func));
00388     if (!ok) {
00389         myCurrentIsBroken = true;
00390         return;
00391     }
00392     if (SUMOXMLDefinitions::EdgeFunctions.hasString(funcString)) {
00393         func = SUMOXMLDefinitions::EdgeFunctions.get(funcString);
00394     } else {
00395         WRITE_ERROR("Edge '" + id + "' has an invalid type ('" + funcString + "').");
00396         myCurrentIsBroken = true;
00397         return;
00398     }
00399     // interpret the function
00400     MSEdge::EdgeBasicFunction funcEnum = MSEdge::EDGEFUNCTION_UNKNOWN;
00401     switch (func) {
00402         case EDGEFUNC_NORMAL:
00403             funcEnum = MSEdge::EDGEFUNCTION_NORMAL;
00404             break;
00405         case EDGEFUNC_CONNECTOR:
00406         case EDGEFUNC_SINK:
00407         case EDGEFUNC_SOURCE:
00408             funcEnum = MSEdge::EDGEFUNCTION_CONNECTOR;
00409             break;
00410         case EDGEFUNC_INTERNAL:
00411             funcEnum = MSEdge::EDGEFUNCTION_INTERNAL;
00412             break;
00413     }
00414     // get the street name
00415     std::string streetName = attrs.getOptStringReporting(SUMO_ATTR_NAME, id.c_str(), ok, "");
00416     if (!ok) {
00417         myCurrentIsBroken = true;
00418         return;
00419     }
00420     //
00421     try {
00422         myEdgeControlBuilder.beginEdgeParsing(id, funcEnum, streetName);
00423     } catch (InvalidArgument& e) {
00424         WRITE_ERROR(e.what());
00425         myCurrentIsBroken = true;
00426     }
00427 }
00428 
00429 
00430 void
00431 NLHandler::closeEdge() {
00432     // omit internal edges if not wished and broken edges
00433     if (myCurrentIsInternalToSkip || myCurrentIsBroken) {
00434         return;
00435     }
00436     try {
00437         MSEdge* e = myEdgeControlBuilder.closeEdge();
00438         MSEdge::dictionary(e->getID(), e);
00439     } catch (InvalidArgument& e) {
00440         WRITE_ERROR(e.what());
00441     }
00442 }
00443 
00444 
00445 //             ---- the root/edge/lanes/lane - element
00446 void
00447 NLHandler::addLane(const SUMOSAXAttributes& attrs) {
00448     // omit internal edges if not wished and broken edges
00449     if (myCurrentIsInternalToSkip || myCurrentIsBroken) {
00450         return;
00451     }
00452     bool ok = true;
00453     // get the id, report an error if not given or empty...
00454     std::string id = attrs.getStringReporting(SUMO_ATTR_ID, 0, ok);
00455     if (!ok) {
00456         myCurrentIsBroken = true;
00457         return;
00458     }
00459     SUMOReal maxSpeed = attrs.hasAttribute(SUMO_ATTR_SPEED)
00460                         ? attrs.getSUMORealReporting(SUMO_ATTR_SPEED, id.c_str(), ok)
00461                         : attrs.getSUMORealReporting(SUMO_ATTR_MAXSPEED__DEPRECATED, id.c_str(), ok);
00462     SUMOReal length = attrs.getSUMORealReporting(SUMO_ATTR_LENGTH, id.c_str(), ok);
00463     std::string allow = attrs.getOptStringReporting(SUMO_ATTR_ALLOW, id.c_str(), ok, "");
00464     std::string disallow = attrs.getOptStringReporting(SUMO_ATTR_DISALLOW, id.c_str(), ok, "");
00465     SUMOReal width = attrs.getOptSUMORealReporting(SUMO_ATTR_WIDTH, id.c_str(), ok, SUMO_const_laneWidth);
00466     int index = attrs.getOptIntReporting(SUMO_ATTR_INDEX, id.c_str(), ok, -1);
00467     PositionVector shape = GeomConvHelper::parseShapeReporting(attrs.getStringReporting(SUMO_ATTR_SHAPE, id.c_str(), ok), "lane", id.c_str(), ok, false);
00468     if (shape.size() < 2) {
00469         WRITE_ERROR("Shape of lane '" + id + "' is broken.\n Can not build according edge.");
00470         myCurrentIsBroken = true;
00471         return;
00472     }
00473     SVCPermissions permissions = parseVehicleClasses(allow, disallow);
00474     myCurrentIsBroken |= !ok;
00475     if (!myCurrentIsBroken) {
00476         try {
00477             MSLane* lane = myEdgeControlBuilder.addLane(id, maxSpeed, length, shape, width, permissions);
00478             // insert the lane into the lane-dictionary, checking
00479             if (!MSLane::dictionary(id, lane)) {
00480                 delete lane;
00481                 WRITE_ERROR("Another lane with the id '" + id + "' exists.");
00482                 myCurrentIsBroken = true;
00483             }
00484         } catch (InvalidArgument& e) {
00485             WRITE_ERROR(e.what());
00486         }
00487     }
00488 }
00489 
00490 
00491 // ---- the root/junction - element
00492 void
00493 NLHandler::openJunction(const SUMOSAXAttributes& attrs) {
00494     myCurrentIsBroken = false;
00495     bool ok = true;
00496     // get the id, report an error if not given or empty...
00497     std::string id = attrs.getStringReporting(SUMO_ATTR_ID, 0, ok);
00498     if (!ok) {
00499         myCurrentIsBroken = true;
00500         return;
00501     }
00502     PositionVector shape;
00503     if (attrs.hasAttribute(SUMO_ATTR_SHAPE)) {
00504         // inner junctions have no shape
00505         shape = GeomConvHelper::parseShapeReporting(attrs.getStringSecure(SUMO_ATTR_SHAPE, ""), attrs.getObjectType(), id.c_str(), ok, true);
00506     }
00507     SUMOReal x = attrs.getSUMORealReporting(SUMO_ATTR_X, id.c_str(), ok);
00508     SUMOReal y = attrs.getSUMORealReporting(SUMO_ATTR_Y, id.c_str(), ok);
00509     std::string type = attrs.getStringReporting(SUMO_ATTR_TYPE, id.c_str(), ok);
00510     std::string key = attrs.getOptStringReporting(SUMO_ATTR_KEY, id.c_str(), ok, "");
00511     // incoming lanes
00512     std::vector<MSLane*> incomingLanes;
00513     parseLanes(id, attrs.getStringSecure(SUMO_ATTR_INCLANES, ""), incomingLanes, ok);
00514     // internal lanes
00515     std::vector<MSLane*> internalLanes;
00516 #ifdef HAVE_INTERNAL_LANES
00517     if (MSGlobals::gUsingInternalLanes) {
00518         parseLanes(id, attrs.getStringSecure(SUMO_ATTR_INTLANES, ""), internalLanes, ok);
00519     }
00520 #endif
00521     if (!ok) {
00522         myCurrentIsBroken = true;
00523     } else {
00524         try {
00525             myJunctionControlBuilder.openJunction(id, key, type, x, y, shape, incomingLanes, internalLanes);
00526         } catch (InvalidArgument& e) {
00527             WRITE_ERROR(e.what() + std::string("\n Can not build according junction."));
00528             myCurrentIsBroken = true;
00529         }
00530     }
00531 }
00532 
00533 
00534 void
00535 NLHandler::parseLanes(const std::string& junctionID,
00536                       const std::string& def, std::vector<MSLane*> &into, bool& ok) {
00537     StringTokenizer st(def);
00538     while (ok && st.hasNext()) {
00539         std::string laneID = st.next();
00540         MSLane* lane = MSLane::dictionary(laneID);
00541         if (!MSGlobals::gUsingInternalLanes && laneID[0] == ':') {
00542             continue;
00543         }
00544         if (lane == 0) {
00545             WRITE_ERROR("An unknown lane ('" + laneID + "') was tried to be set as incoming to junction '" + junctionID + "'.");
00546             ok = false;
00547             continue;
00548         }
00549         into.push_back(lane);
00550     }
00551 }
00552 // ----
00553 
00554 void
00555 NLHandler::addParam(const SUMOSAXAttributes& attrs) {
00556     bool ok = true;
00557     std::string key = attrs.getStringReporting(SUMO_ATTR_KEY, 0, ok);
00558     std::string val = attrs.getStringReporting(SUMO_ATTR_VALUE, 0, ok);
00559     // set
00560     if (ok && myAmInTLLogicMode) {
00561         assert(key != "");
00562         assert(val != "");
00563         myJunctionControlBuilder.addParam(key, val);
00564     }
00565 }
00566 
00567 
00568 void
00569 NLHandler::openWAUT(const SUMOSAXAttributes& attrs) {
00570     myCurrentIsBroken = false;
00571     bool ok = true;
00572     // get the id, report an error if not given or empty...
00573     std::string id = attrs.getStringReporting(SUMO_ATTR_ID, 0, ok);
00574     if (!ok) {
00575         myCurrentIsBroken = true;
00576         return;
00577     }
00578     SUMOTime t = attrs.getOptSUMOTimeReporting(SUMO_ATTR_REF_TIME, id.c_str(), ok, 0);
00579     std::string pro = attrs.getStringReporting(SUMO_ATTR_START_PROG, id.c_str(), ok);
00580     if (!ok) {
00581         myCurrentIsBroken = true;
00582     }
00583     if (!myCurrentIsBroken) {
00584         myCurrentWAUTID = id;
00585         try {
00586             myJunctionControlBuilder.getTLLogicControlToUse().addWAUT(t, id, pro);
00587         } catch (InvalidArgument& e) {
00588             WRITE_ERROR(e.what());
00589             myCurrentIsBroken = true;
00590         }
00591     }
00592 }
00593 
00594 
00595 void
00596 NLHandler::addWAUTSwitch(const SUMOSAXAttributes& attrs) {
00597     bool ok = true;
00598     SUMOTime t = attrs.getSUMOTimeReporting(SUMO_ATTR_TIME, myCurrentWAUTID.c_str(), ok);
00599     std::string to = attrs.getStringReporting(SUMO_ATTR_TO, myCurrentWAUTID.c_str(), ok);
00600     if (!ok) {
00601         myCurrentIsBroken = true;
00602     }
00603     if (!myCurrentIsBroken) {
00604         try {
00605             myJunctionControlBuilder.getTLLogicControlToUse().addWAUTSwitch(myCurrentWAUTID, t, to);
00606         } catch (InvalidArgument& e) {
00607             WRITE_ERROR(e.what());
00608             myCurrentIsBroken = true;
00609         }
00610     }
00611 }
00612 
00613 
00614 void
00615 NLHandler::addWAUTJunction(const SUMOSAXAttributes& attrs) {
00616     bool ok = true;
00617     std::string wautID = attrs.getStringReporting(SUMO_ATTR_WAUT_ID, 0, ok);
00618     std::string junctionID = attrs.getStringReporting(SUMO_ATTR_JUNCTION_ID, 0, ok);
00619     std::string procedure = attrs.getOptStringReporting(SUMO_ATTR_PROCEDURE, 0, ok, "");
00620     bool synchron = attrs.getOptBoolReporting(SUMO_ATTR_SYNCHRON, 0, ok, false);
00621     if (!ok) {
00622         myCurrentIsBroken = true;
00623     }
00624     try {
00625         if (!myCurrentIsBroken) {
00626             myJunctionControlBuilder.getTLLogicControlToUse().addWAUTJunction(wautID, junctionID, procedure, synchron);
00627         }
00628     } catch (InvalidArgument& e) {
00629         WRITE_ERROR(e.what());
00630         myCurrentIsBroken = true;
00631     }
00632 }
00633 
00634 
00635 
00636 
00637 
00638 
00639 
00640 void
00641 NLHandler::addPOI(const SUMOSAXAttributes& attrs) {
00642     bool ok = true;
00643     const SUMOReal INVALID_POSITION(-1000000);
00644     std::string id = attrs.getStringReporting(SUMO_ATTR_ID, 0, ok);
00645     SUMOReal x = attrs.getOptSUMORealReporting(SUMO_ATTR_X, id.c_str(), ok, INVALID_POSITION);
00646     SUMOReal y = attrs.getOptSUMORealReporting(SUMO_ATTR_Y, id.c_str(), ok, INVALID_POSITION);
00647     SUMOReal lanePos = attrs.getOptSUMORealReporting(SUMO_ATTR_POSITION, id.c_str(), ok, INVALID_POSITION);
00648     int layer = attrs.getOptIntReporting(SUMO_ATTR_LAYER, id.c_str(), ok, GLO_SHAPE);
00649     std::string type = attrs.getOptStringReporting(SUMO_ATTR_TYPE, id.c_str(), ok, "");
00650     std::string laneID = attrs.getOptStringReporting(SUMO_ATTR_LANE, id.c_str(), ok, "");
00651     std::string colorStr = attrs.getOptStringReporting(SUMO_ATTR_COLOR, id.c_str(), ok, "1,0,0");
00652     RGBColor color = RGBColor::parseColorReporting(colorStr, attrs.getObjectType(), id.c_str(), true, ok);
00653     if (!ok) {
00654         return;
00655     }
00656     Position pos(x, y);
00657     if (x == INVALID_POSITION || y == INVALID_POSITION) {
00658         MSLane* lane = MSLane::dictionary(laneID);
00659         if (lane == 0) {
00660             WRITE_ERROR("Lane '" + laneID + "' to place a poi '" + id + "'on is not known.");
00661             return;
00662         }
00663         if (lanePos < 0) {
00664             lanePos = lane->getLength() + lanePos;
00665         }
00666         pos = lane->getShape().positionAtLengthPosition(lanePos);
00667     }
00668     if (!myNet.getShapeContainer().addPoI(id, layer, type, color, pos)) {
00669         WRITE_ERROR("PoI '" + id + "' already exists.");
00670     }
00671 }
00672 
00673 
00674 void
00675 NLHandler::addPoly(const SUMOSAXAttributes& attrs) {
00676     bool ok = true;
00677     std::string id = attrs.getStringReporting(SUMO_ATTR_ID, 0, ok);
00678     // get the id, report an error if not given or empty...
00679     if (!ok) {
00680         return;
00681     }
00682     int layer = attrs.getOptIntReporting(SUMO_ATTR_LAYER, id.c_str(), ok, GLO_SHAPE);
00683     bool fill = attrs.getOptBoolReporting(SUMO_ATTR_FILL, id.c_str(), ok, false);
00684     std::string type = attrs.getOptStringReporting(SUMO_ATTR_TYPE, id.c_str(), ok, "");
00685     std::string colorStr = attrs.getStringReporting(SUMO_ATTR_COLOR, id.c_str(), ok);
00686     RGBColor color = RGBColor::parseColorReporting(colorStr, attrs.getObjectType(), id.c_str(), true, ok);
00687     PositionVector shape = GeomConvHelper::parseShapeReporting(attrs.getStringReporting(SUMO_ATTR_SHAPE, id.c_str(), ok), attrs.getObjectType(), id.c_str(), ok, false);
00688     if (shape.size() != 0) {
00689         if (!myNet.getShapeContainer().addPolygon(id, layer, type, color, fill, shape)) {
00690             WRITE_ERROR("Polygon '" + id + "' already exists.");
00691         }
00692     }
00693 }
00694 
00695 
00696 void
00697 NLHandler::addLogicItem(const SUMOSAXAttributes& attrs) {
00698     bool ok = true;
00699     int request = attrs.getIntReporting(SUMO_ATTR_REQUEST, 0, ok);
00700     bool cont = false;
00701 #ifdef HAVE_INTERNAL_LANES
00702     cont = attrs.getOptBoolReporting(SUMO_ATTR_CONT, 0, ok, false);
00703 #endif
00704     std::string response = attrs.getStringReporting(SUMO_ATTR_RESPONSE, 0, ok);
00705     std::string foes = attrs.getStringReporting(SUMO_ATTR_FOES, 0, ok);
00706     if (!ok) {
00707         return;
00708     }
00709     // store received information
00710     if (request >= 0 && response.length() > 0) {
00711         try {
00712             myJunctionControlBuilder.addLogicItem(request, response, foes, cont);
00713         } catch (InvalidArgument& e) {
00714             WRITE_ERROR(e.what());
00715         }
00716     }
00717 }
00718 
00719 
00720 void
00721 NLHandler::addRequest(const SUMOSAXAttributes& attrs) {
00722     if (myCurrentIsBroken) {
00723         return;
00724     }
00725     bool ok = true;
00726     int request = attrs.getIntReporting(SUMO_ATTR_INDEX, 0, ok);
00727     bool cont = false;
00728 #ifdef HAVE_INTERNAL_LANES
00729     cont = attrs.getOptBoolReporting(SUMO_ATTR_CONT, 0, ok, false);
00730 #endif
00731     std::string response = attrs.getStringReporting(SUMO_ATTR_RESPONSE, 0, ok);
00732     std::string foes = attrs.getStringReporting(SUMO_ATTR_FOES, 0, ok);
00733     if (!ok) {
00734         return;
00735     }
00736     // store received information
00737     if (request >= 0 && response.length() > 0) {
00738         try {
00739             myJunctionControlBuilder.addLogicItem(request, response, foes, cont);
00740         } catch (InvalidArgument& e) {
00741             WRITE_ERROR(e.what());
00742         }
00743     }
00744 }
00745 
00746 
00747 void
00748 NLHandler::initJunctionLogic(const SUMOSAXAttributes& attrs) {
00749     if (myCurrentIsBroken) {
00750         return;
00751     }
00752     bool ok = true;
00753     // we either a have a junction or a legacy network with ROWLogic
00754     std::string id = attrs.getStringReporting(SUMO_ATTR_ID, 0, ok);
00755     if (ok) {
00756         myJunctionControlBuilder.initJunctionLogic(id);
00757     }
00758 }
00759 
00760 
00761 void
00762 NLHandler::initTrafficLightLogic(const SUMOSAXAttributes& attrs) {
00763     myAmInTLLogicMode = true;
00764     bool ok = true;
00765     std::string id = attrs.getStringReporting(SUMO_ATTR_ID, 0, ok);
00766     TrafficLightType type;
00767     std::string typeS = attrs.getStringReporting(SUMO_ATTR_TYPE, 0, ok);
00768     if (SUMOXMLDefinitions::TrafficLightTypes.hasString(typeS)) {
00769         type = SUMOXMLDefinitions::TrafficLightTypes.get(typeS);
00770     } else {
00771         WRITE_ERROR("Traffic light '" + id + "' has unknown type '" + typeS + "'");
00772         return;
00773     }
00774     //
00775     SUMOTime offset = attrs.getOptSUMOTimeReporting(SUMO_ATTR_OFFSET, id.c_str(), ok, 0);
00776     if (!ok) {
00777         return;
00778     }
00779     std::string programID = attrs.getOptStringReporting(SUMO_ATTR_PROGRAMID, id.c_str(), ok, "<unknown>");
00780     myJunctionControlBuilder.initTrafficLightLogic(id, programID, type, offset);
00781 }
00782 
00783 
00784 void
00785 NLHandler::addPhase(const SUMOSAXAttributes& attrs) {
00786     // try to get the phase definition
00787     bool ok = true;
00788     std::string state = attrs.getStringReporting(SUMO_ATTR_STATE, 0, ok);
00789     if (!ok) {
00790         return;
00791     }
00792     // try to get the phase duration
00793     SUMOTime duration = attrs.getSUMOTimeReporting(SUMO_ATTR_DURATION, myJunctionControlBuilder.getActiveKey().c_str(), ok);
00794     if (duration == 0) {
00795         WRITE_ERROR("Duration of tls-logic '" + myJunctionControlBuilder.getActiveKey() + "/" + myJunctionControlBuilder.getActiveSubKey() + "' is zero.");
00796         return;
00797     }
00798     // if the traffic light is an actuated traffic light, try to get
00799     //  the minimum and maximum durations
00800     SUMOTime minDuration = -1;
00801     if (attrs.hasAttribute(SUMO_ATTR_MINDURATION__DEPRECATED)) {
00802         minDuration = attrs.getSUMOTimeReporting(SUMO_ATTR_MINDURATION__DEPRECATED, myJunctionControlBuilder.getActiveKey().c_str(), ok);
00803         if (!myHaveWarnedAboutDeprecatedTLSTiming) {
00804             myHaveWarnedAboutDeprecatedTLSTiming = true;
00805             WRITE_WARNING("Your tls definition contains deprecated minimum/maximum duration attribute; use minDur and maxDur instead.");
00806         }
00807     } else {
00808         minDuration = attrs.getOptSUMOTimeReporting(SUMO_ATTR_MINDURATION, myJunctionControlBuilder.getActiveKey().c_str(), ok, -1);
00809     }
00810     SUMOTime maxDuration = -1;
00811     if (attrs.hasAttribute(SUMO_ATTR_MAXDURATION__DEPRECATED)) {
00812         maxDuration = attrs.getSUMOTimeReporting(SUMO_ATTR_MAXDURATION__DEPRECATED, myJunctionControlBuilder.getActiveKey().c_str(), ok);
00813         if (!myHaveWarnedAboutDeprecatedTLSTiming) {
00814             myHaveWarnedAboutDeprecatedTLSTiming = true;
00815             WRITE_WARNING("Your tls definition contains deprecated minimum/maximum duration attribute; use minDur and maxDur instead.");
00816         }
00817     } else {
00818         maxDuration = attrs.getOptSUMOTimeReporting(SUMO_ATTR_MAXDURATION, myJunctionControlBuilder.getActiveKey().c_str(), ok, -1);
00819     }
00820     myJunctionControlBuilder.addPhase(duration, state, minDuration, maxDuration);
00821 }
00822 
00823 
00824 #ifdef _MESSAGES
00825 void
00826 NLHandler::addMsgEmitter(const SUMOSAXAttributes& attrs) {
00827     bool ok = true;
00828     std::string id = attrs.getStringReporting(SUMO_ATTR_ID, 0, ok);
00829     std::string file = attrs.getOptStringReporting(SUMO_ATTR_FILE, 0, ok, "");
00830     // if no file given, use stdout
00831     if (file == "") {
00832         file = "-";
00833     }
00834     SUMOTime step = attrs.getOptSUMOTimeReporting(SUMO_ATTR_STEP, id.c_str(), ok, 1);
00835     bool reverse = attrs.getOptBoolReporting(SUMO_ATTR_REVERSE, 0, ok, false);
00836     bool table = attrs.getOptBoolReporting(SUMO_ATTR_TABLE, 0, ok, false);
00837     bool xycoord = attrs.getOptBoolReporting(SUMO_ATTR_XY, 0, ok, false);
00838     std::string whatemit = attrs.getStringReporting(SUMO_ATTR_EVENTS, 0, ok);
00839     if (!ok) {
00840         return;
00841     }
00842     myNet.createMsgEmitter(id, file, getFileName(), whatemit, reverse, table, xycoord, step);
00843 }
00844 #endif
00845 
00846 
00847 void
00848 NLHandler::addE1Detector(const SUMOSAXAttributes& attrs) {
00849     bool ok = true;
00850     // get the id, report an error if not given or empty...
00851     std::string id = attrs.getStringReporting(SUMO_ATTR_ID, 0, ok);
00852     if (!ok) {
00853         return;
00854     }
00855     // inform the user about deprecated values
00856     const SUMOTime frequency = attrs.getSUMOTimeReporting(SUMO_ATTR_FREQUENCY, id.c_str(), ok);
00857     const SUMOReal position = attrs.getSUMORealReporting(SUMO_ATTR_POSITION, id.c_str(), ok);
00858     const bool friendlyPos = attrs.getOptBoolReporting(SUMO_ATTR_FRIENDLY_POS, id.c_str(), ok, false);
00859     const bool splitByType = attrs.getOptBoolReporting(SUMO_ATTR_SPLIT_VTYPE, id.c_str(), ok, false);
00860     const std::string lane = attrs.getStringReporting(SUMO_ATTR_LANE, id.c_str(), ok);
00861     const std::string file = attrs.getStringReporting(SUMO_ATTR_FILE, id.c_str(), ok);
00862     if (!ok) {
00863         return;
00864     }
00865     try {
00866         myDetectorBuilder.buildInductLoop(id, lane, position, frequency,
00867                                           OutputDevice::getDevice(file, getFileName()),
00868                                           friendlyPos, splitByType);
00869     } catch (InvalidArgument& e) {
00870         WRITE_ERROR(e.what());
00871     } catch (IOError& e) {
00872         WRITE_ERROR(e.what());
00873     }
00874 }
00875 
00876 
00877 void
00878 NLHandler::addInstantE1Detector(const SUMOSAXAttributes& attrs) {
00879     bool ok = true;
00880     // get the id, report an error if not given or empty...
00881     std::string id = attrs.getStringReporting(SUMO_ATTR_ID, 0, ok);
00882     if (!ok) {
00883         return;
00884     }
00885     // inform the user about deprecated values
00886     const SUMOReal position = attrs.getSUMORealReporting(SUMO_ATTR_POSITION, id.c_str(), ok);
00887     const bool friendlyPos = attrs.getOptBoolReporting(SUMO_ATTR_FRIENDLY_POS, id.c_str(), ok, false);
00888     const std::string lane = attrs.getStringReporting(SUMO_ATTR_LANE, id.c_str(), ok);
00889     const std::string file = attrs.getStringReporting(SUMO_ATTR_FILE, id.c_str(), ok);
00890     if (!ok) {
00891         return;
00892     }
00893     try {
00894         myDetectorBuilder.buildInstantInductLoop(id, lane, position, OutputDevice::getDevice(file, getFileName()), friendlyPos);
00895     } catch (InvalidArgument& e) {
00896         WRITE_ERROR(e.what());
00897     } catch (IOError& e) {
00898         WRITE_ERROR(e.what());
00899     }
00900 }
00901 
00902 
00903 void
00904 NLHandler::addVTypeProbeDetector(const SUMOSAXAttributes& attrs) {
00905     bool ok = true;
00906     std::string id = attrs.getStringReporting(SUMO_ATTR_ID, 0, ok);
00907     SUMOTime frequency = attrs.getSUMOTimeReporting(SUMO_ATTR_FREQUENCY, id.c_str(), ok);
00908     std::string type = attrs.getStringSecure(SUMO_ATTR_TYPE, "");
00909     std::string file = attrs.getStringReporting(SUMO_ATTR_FILE, id.c_str(), ok);
00910     if (!ok) {
00911         return;
00912     }
00913     try {
00914         myDetectorBuilder.buildVTypeProbe(id, type, frequency, OutputDevice::getDevice(file, getFileName()));
00915     } catch (InvalidArgument& e) {
00916         WRITE_ERROR(e.what());
00917     } catch (IOError& e) {
00918         WRITE_ERROR(e.what());
00919     }
00920 }
00921 
00922 
00923 void
00924 NLHandler::addRouteProbeDetector(const SUMOSAXAttributes& attrs) {
00925     bool ok = true;
00926     std::string id = attrs.getStringReporting(SUMO_ATTR_ID, 0, ok);
00927     SUMOTime frequency = attrs.getSUMOTimeReporting(SUMO_ATTR_FREQUENCY, id.c_str(), ok);
00928     SUMOTime begin = attrs.getOptSUMOTimeReporting(SUMO_ATTR_BEGIN, id.c_str(), ok, -1);
00929     std::string edge = attrs.getStringReporting(SUMO_ATTR_EDGE, id.c_str(), ok);
00930     std::string file = attrs.getStringReporting(SUMO_ATTR_FILE, id.c_str(), ok);
00931     if (!ok) {
00932         return;
00933     }
00934     try {
00935         myDetectorBuilder.buildRouteProbe(id, edge, frequency, begin,
00936                                           OutputDevice::getDevice(file, getFileName()));
00937     } catch (InvalidArgument& e) {
00938         WRITE_ERROR(e.what());
00939     } catch (IOError& e) {
00940         WRITE_ERROR(e.what());
00941     }
00942 }
00943 
00944 
00945 
00946 void
00947 NLHandler::addE2Detector(const SUMOSAXAttributes& attrs) {
00948     // check whether this is a detector connected to a tls an optionally to a link
00949     bool ok = true;
00950     const std::string id = attrs.getStringReporting(SUMO_ATTR_ID, 0, ok);
00951     const std::string lsaid = attrs.getOptStringReporting(SUMO_ATTR_TLID, id.c_str(), ok, "<invalid>");
00952     const std::string toLane = attrs.getOptStringReporting(SUMO_ATTR_TO, id.c_str(), ok, "<invalid>");
00953     const SUMOTime haltingTimeThreshold = attrs.getOptSUMOTimeReporting(SUMO_ATTR_HALTING_TIME_THRESHOLD, id.c_str(), ok, TIME2STEPS(1));
00954     const SUMOReal haltingSpeedThreshold = attrs.getOptSUMORealReporting(SUMO_ATTR_HALTING_SPEED_THRESHOLD, id.c_str(), ok, 5.0f / 3.6f);
00955     const SUMOReal jamDistThreshold = attrs.getOptSUMORealReporting(SUMO_ATTR_JAM_DIST_THRESHOLD, id.c_str(), ok, 10.0f);
00956     const SUMOReal position = attrs.getSUMORealReporting(SUMO_ATTR_POSITION, id.c_str(), ok);
00957     const SUMOReal length = attrs.getSUMORealReporting(SUMO_ATTR_LENGTH, id.c_str(), ok);
00958     const bool friendlyPos = attrs.getOptBoolReporting(SUMO_ATTR_FRIENDLY_POS, id.c_str(), ok, false);
00959     const bool cont = attrs.getOptBoolReporting(SUMO_ATTR_CONT, id.c_str(), ok, false);
00960     const std::string lane = attrs.getStringReporting(SUMO_ATTR_LANE, id.c_str(), ok);
00961     const std::string file = attrs.getStringReporting(SUMO_ATTR_FILE, id.c_str(), ok);
00962     if (!ok) {
00963         return;
00964     }
00965     try {
00966         if (lsaid != "<invalid>") {
00967             if (toLane == "<invalid>") {
00968                 myDetectorBuilder.buildE2Detector(id, lane, position, length, cont,
00969                                                   myJunctionControlBuilder.getTLLogic(lsaid),
00970                                                   OutputDevice::getDevice(file, getFileName()),
00971                                                   haltingTimeThreshold, haltingSpeedThreshold, jamDistThreshold,
00972                                                   friendlyPos);
00973             } else {
00974                 myDetectorBuilder.buildE2Detector(id, lane, position, length, cont,
00975                                                   myJunctionControlBuilder.getTLLogic(lsaid), toLane,
00976                                                   OutputDevice::getDevice(file, getFileName()),
00977                                                   haltingTimeThreshold, haltingSpeedThreshold, jamDistThreshold,
00978                                                   friendlyPos);
00979             }
00980         } else {
00981             bool ok = true;
00982             SUMOTime frequency = attrs.getSUMOTimeReporting(SUMO_ATTR_FREQUENCY, id.c_str(), ok);
00983             if (!ok) {
00984                 return;
00985             }
00986             myDetectorBuilder.buildE2Detector(id, lane, position, length, cont, frequency,
00987                                               OutputDevice::getDevice(file, getFileName()),
00988                                               haltingTimeThreshold, haltingSpeedThreshold, jamDistThreshold,
00989                                               friendlyPos);
00990         }
00991     } catch (InvalidArgument& e) {
00992         WRITE_ERROR(e.what());
00993     } catch (IOError& e) {
00994         WRITE_ERROR(e.what());
00995     }
00996 }
00997 
00998 
00999 void
01000 NLHandler::beginE3Detector(const SUMOSAXAttributes& attrs) {
01001     bool ok = true;
01002     // inform the user about deprecated values
01003     std::string id = attrs.getStringReporting(SUMO_ATTR_ID, 0, ok);
01004     if (attrs.hasAttribute(SUMO_ATTR_HALTING_TIME_THRESHOLD__DEPRECATED)) {
01005         myHaveWarnedAboutDeprecatedTimeThreshold = true;
01006         WRITE_WARNING("'" + toString(SUMO_ATTR_HALTING_TIME_THRESHOLD__DEPRECATED) + "' is deprecated; please use '" + toString(SUMO_ATTR_HALTING_TIME_THRESHOLD) + "'.");
01007     }
01008     if (attrs.hasAttribute(SUMO_ATTR_HALTING_SPEED_THRESHOLD__DEPRECATED)) {
01009         myHaveWarnedAboutDeprecatedSpeedThreshold = true;
01010         WRITE_WARNING("'" + toString(SUMO_ATTR_HALTING_SPEED_THRESHOLD__DEPRECATED) + "' is deprecated; please use '" + toString(SUMO_ATTR_HALTING_SPEED_THRESHOLD) + "'.");
01011     }
01012 
01013     const SUMOTime frequency = attrs.getSUMOTimeReporting(SUMO_ATTR_FREQUENCY, id.c_str(), ok);
01014     const SUMOTime haltingTimeThreshold = attrs.hasAttribute(SUMO_ATTR_HALTING_TIME_THRESHOLD__DEPRECATED)
01015                                           ? attrs.getOptSUMOTimeReporting(SUMO_ATTR_HALTING_TIME_THRESHOLD__DEPRECATED, id.c_str(), ok, TIME2STEPS(1))
01016                                           : attrs.getOptSUMOTimeReporting(SUMO_ATTR_HALTING_TIME_THRESHOLD, id.c_str(), ok, TIME2STEPS(1));
01017     const SUMOReal haltingSpeedThreshold = attrs.hasAttribute(SUMO_ATTR_HALTING_SPEED_THRESHOLD__DEPRECATED)
01018                                            ? attrs.getOptSUMORealReporting(SUMO_ATTR_HALTING_SPEED_THRESHOLD__DEPRECATED, id.c_str(), ok, 5.0f / 3.6f)
01019                                            : attrs.getOptSUMORealReporting(SUMO_ATTR_HALTING_SPEED_THRESHOLD, id.c_str(), ok, 5.0f / 3.6f);
01020     const std::string file = attrs.getStringReporting(SUMO_ATTR_FILE, id.c_str(), ok);
01021     if (!ok) {
01022         return;
01023     }
01024     try {
01025         myDetectorBuilder.beginE3Detector(id,
01026                                           OutputDevice::getDevice(file, getFileName()),
01027                                           frequency, haltingSpeedThreshold, haltingTimeThreshold);
01028     } catch (InvalidArgument& e) {
01029         WRITE_ERROR(e.what());
01030     } catch (IOError& e) {
01031         WRITE_ERROR(e.what());
01032     }
01033 }
01034 
01035 
01036 void
01037 NLHandler::addE3Entry(const SUMOSAXAttributes& attrs) {
01038     bool ok = true;
01039     const SUMOReal position = attrs.getSUMORealReporting(SUMO_ATTR_POSITION, myDetectorBuilder.getCurrentE3ID().c_str(), ok);
01040     const bool friendlyPos = attrs.getOptBoolReporting(SUMO_ATTR_FRIENDLY_POS, myDetectorBuilder.getCurrentE3ID().c_str(), ok, false);
01041     const std::string lane = attrs.getStringReporting(SUMO_ATTR_LANE, myDetectorBuilder.getCurrentE3ID().c_str(), ok);
01042     if (!ok) {
01043         return;
01044     }
01045     myDetectorBuilder.addE3Entry(lane, position, friendlyPos);
01046 }
01047 
01048 
01049 void
01050 NLHandler::addE3Exit(const SUMOSAXAttributes& attrs) {
01051     bool ok = true;
01052     const SUMOReal position = attrs.getSUMORealReporting(SUMO_ATTR_POSITION, myDetectorBuilder.getCurrentE3ID().c_str(), ok);
01053     const bool friendlyPos = attrs.getOptBoolReporting(SUMO_ATTR_FRIENDLY_POS, myDetectorBuilder.getCurrentE3ID().c_str(), ok, false);
01054     const std::string lane = attrs.getStringReporting(SUMO_ATTR_LANE, myDetectorBuilder.getCurrentE3ID().c_str(), ok);
01055     if (!ok) {
01056         return;
01057     }
01058     myDetectorBuilder.addE3Exit(lane, position, friendlyPos);
01059 }
01060 
01061 
01062 void
01063 NLHandler::addEdgeLaneMeanData(const SUMOSAXAttributes& attrs, int objecttype) {
01064     bool ok = true;
01065     std::string id = attrs.getStringReporting(SUMO_ATTR_ID, 0, ok);
01066     const SUMOReal maxTravelTime = attrs.getOptSUMORealReporting(SUMO_ATTR_MAX_TRAVELTIME, id.c_str(), ok, 100000);
01067     const SUMOReal minSamples = attrs.getOptSUMORealReporting(SUMO_ATTR_MIN_SAMPLES, id.c_str(), ok, 0);
01068     const SUMOReal haltingSpeedThreshold = attrs.getOptSUMORealReporting(SUMO_ATTR_HALTING_SPEED_THRESHOLD, id.c_str(), ok, POSITION_EPS);
01069     const std::string excludeEmpty = attrs.getOptStringReporting(SUMO_ATTR_EXCLUDE_EMPTY, id.c_str(), ok, "false");
01070     const bool withInternal = attrs.getOptBoolReporting(SUMO_ATTR_WITH_INTERNAL, id.c_str(), ok, false);
01071     const bool trackVehicles = attrs.getOptBoolReporting(SUMO_ATTR_TRACK_VEHICLES, id.c_str(), ok, false);
01072     const std::string file = attrs.getStringReporting(SUMO_ATTR_FILE, id.c_str(), ok);
01073     const std::string type = attrs.getOptStringReporting(SUMO_ATTR_TYPE, id.c_str(), ok, "performance");
01074     std::string vtypes = attrs.getOptStringReporting(SUMO_ATTR_VTYPES, id.c_str(), ok, "");
01075     if (attrs.hasAttribute(SUMO_ATTR_VTYPES__DEPRECATED)) {
01076         vtypes = attrs.getStringReporting(SUMO_ATTR_VTYPES__DEPRECATED, id.c_str(), ok);
01077         if (!myHaveWarnedAboutDeprecatedVTypes) {
01078             WRITE_WARNING("'" + toString(SUMO_ATTR_VTYPES__DEPRECATED) + " is deprecated; please use '" + toString(SUMO_ATTR_VTYPES) + "'.");
01079             myHaveWarnedAboutDeprecatedVTypes = true;
01080         }
01081     }
01082     const SUMOTime frequency = attrs.getOptSUMOTimeReporting(SUMO_ATTR_FREQUENCY, id.c_str(), ok, -1);
01083     const SUMOTime begin = attrs.getOptSUMOTimeReporting(SUMO_ATTR_BEGIN, id.c_str(), ok, string2time(OptionsCont::getOptions().getString("begin")));
01084     const SUMOTime end = attrs.getOptSUMOTimeReporting(SUMO_ATTR_END, id.c_str(), ok, string2time(OptionsCont::getOptions().getString("end")));
01085     if (!ok) {
01086         return;
01087     }
01088     try {
01089         myDetectorBuilder.createEdgeLaneMeanData(id, frequency, begin, end,
01090                 type, objecttype == SUMO_TAG_MEANDATA_LANE,
01091                 // equivalent to TplConvert::_2bool used in SUMOSAXAttributes::getBool
01092                 excludeEmpty[0] != 't' && excludeEmpty[0] != 'T' && excludeEmpty[0] != '1' && excludeEmpty[0] != 'x',
01093                 excludeEmpty == "defaults", withInternal, trackVehicles,
01094                 maxTravelTime, minSamples, haltingSpeedThreshold, vtypes,
01095                 OutputDevice::getDevice(file, getFileName()));
01096     } catch (InvalidArgument& e) {
01097         WRITE_ERROR(e.what());
01098     } catch (IOError& e) {
01099         WRITE_ERROR(e.what());
01100     }
01101 }
01102 
01103 
01104 
01105 void
01106 NLHandler::openSucc(const SUMOSAXAttributes& attrs) {
01107     bool ok = true;
01108     std::string id = attrs.getStringReporting(SUMO_ATTR_LANE, 0, ok);
01109     if (!MSGlobals::gUsingInternalLanes && id[0] == ':') {
01110         myCurrentIsInternalToSkip = true;
01111         return;
01112     }
01113     myCurrentIsInternalToSkip = false;
01114     mySucceedingLaneBuilder.openSuccLane(id);
01115 }
01116 
01117 
01118 void
01119 NLHandler::addSuccLane(const SUMOSAXAttributes& attrs) {
01120     // do not process internal lanes if not wished
01121     if (myCurrentIsInternalToSkip) {
01122         return;
01123     }
01124     try {
01125         bool ok = true;
01126         SUMOReal pass = attrs.getOptSUMORealReporting(SUMO_ATTR_PASS, 0, ok, -1);
01127         std::string lane = attrs.getStringReporting(SUMO_ATTR_LANE, 0, ok);
01128         std::string dir = attrs.getStringReporting(SUMO_ATTR_DIR, 0, ok);
01129         std::string state = attrs.getStringReporting(SUMO_ATTR_STATE, 0, ok);
01130         std::string tlID = attrs.getOptStringReporting(SUMO_ATTR_TLID, 0, ok, "");
01131 #ifdef HAVE_INTERNAL_LANES
01132         std::string via = attrs.getOptStringReporting(SUMO_ATTR_VIA, 0, ok, "");
01133 #endif
01134         if (!ok) {
01135             return;
01136         }
01137         if (tlID != "") {
01138             int linkNumber = attrs.hasAttribute(SUMO_ATTR_TLLINKINDEX)
01139                              ? attrs.getIntReporting(SUMO_ATTR_TLLINKINDEX, 0, ok)
01140                              : attrs.getIntReporting(SUMO_ATTR_TLLINKNO__DEPRECATED, 0, ok);
01141             if (!ok) {
01142                 return;
01143             }
01144             mySucceedingLaneBuilder.addSuccLane(lane,
01145 #ifdef HAVE_INTERNAL_LANES
01146                                                 via, pass,
01147 #endif
01148                                                 parseLinkDir(dir), parseLinkState(state), tlID, linkNumber);
01149         } else {
01150             mySucceedingLaneBuilder.addSuccLane(lane,
01151 #ifdef HAVE_INTERNAL_LANES
01152                                                 via, pass,
01153 #endif
01154                                                 parseLinkDir(dir), parseLinkState(state));
01155         }
01156     } catch (InvalidArgument& e) {
01157         WRITE_ERROR(e.what());
01158     }
01159 }
01160 
01161 
01162 
01163 void
01164 NLHandler::addConnection(const SUMOSAXAttributes& attrs) {
01165     bool ok = true;
01166     std::string fromID = attrs.getStringReporting(SUMO_ATTR_FROM, 0, ok);
01167     if (!MSGlobals::gUsingInternalLanes && fromID[0] == ':') {
01168         return;
01169     }
01170 
01171     try {
01172         bool ok = true;
01173         std::string toID = attrs.getStringReporting(SUMO_ATTR_TO, 0, ok);
01174         std::string laneIndices;
01175         if (attrs.hasAttribute(SUMO_ATTR_LANE)) {
01176             if (!myHaveWarnedAboutDeprecatedLanes) {
01177                 myHaveWarnedAboutDeprecatedLanes = true;
01178                 WRITE_WARNING("'" + toString(SUMO_ATTR_LANE) + "' is deprecated, please use '" + toString(SUMO_ATTR_FROM_LANE) +
01179                               "' and '" + toString(SUMO_ATTR_TO_LANE) + "' instead.");
01180             }
01181             laneIndices = attrs.getStringReporting(SUMO_ATTR_LANE, 0, ok);
01182         } else {
01183             laneIndices = attrs.getStringReporting(SUMO_ATTR_FROM_LANE, 0, ok) + ":" + attrs.getStringReporting(SUMO_ATTR_TO_LANE, 0, ok);
01184         }
01185         LinkDirection dir = parseLinkDir(attrs.getStringReporting(SUMO_ATTR_DIR, 0, ok));
01186         LinkState state = parseLinkState(attrs.getStringReporting(SUMO_ATTR_STATE, 0, ok));
01187         std::string tlID = attrs.getOptStringReporting(SUMO_ATTR_TLID, 0, ok, "");
01188 #ifdef HAVE_INTERNAL_LANES
01189         std::string viaID = attrs.getOptStringReporting(SUMO_ATTR_VIA, 0, ok, "");
01190         SUMOReal pass = attrs.getOptSUMORealReporting(SUMO_ATTR_PASS, 0, ok, -1);
01191 #endif
01192 
01193         MSEdge* from = MSEdge::dictionary(fromID);
01194         if (from == 0) {
01195             WRITE_ERROR("Unknown from-edge '" + fromID + "' in connection");
01196             return;
01197         }
01198         MSEdge* to = MSEdge::dictionary(toID);
01199         if (to == 0) {
01200             WRITE_ERROR("Unknown to-edge '" + toID + "' in connection");
01201             return;
01202         }
01203         std::pair<MSLane*, MSLane*> lanes = getLanesFromIndices(from, to, laneIndices, ok);
01204         if (!ok) {
01205             return;
01206         }
01207         MSLane* fromLane = lanes.first;
01208         MSLane* toLane = lanes.second;
01209         assert(fromLane);
01210         assert(toLane);
01211 
01212         int tlLinkIdx;
01213         if (tlID != "") {
01214             tlLinkIdx = attrs.hasAttribute(SUMO_ATTR_TLLINKINDEX)
01215                         ? attrs.getIntReporting(SUMO_ATTR_TLLINKINDEX, 0, ok)
01216                         : attrs.getIntReporting(SUMO_ATTR_TLLINKNO__DEPRECATED, 0, ok);
01217             // make sure that the index is in range
01218             MSTrafficLightLogic* logic = myJunctionControlBuilder.getTLLogic(tlID).getActive();
01219             if (tlLinkIdx >= (int)logic->getCurrentPhaseDef().getState().size()) {
01220                 WRITE_ERROR("Invalid " + toString(SUMO_ATTR_TLLINKINDEX) + " '" + toString(tlLinkIdx) +
01221                             "' in connection controlled by '" + tlID + "'");
01222                 return;
01223             }
01224             if (!ok) {
01225                 return;
01226             }
01227         }
01228         SUMOReal length = fromLane->getShape()[-1].distanceTo(toLane->getShape()[0]);
01229         MSLink* link = 0;
01230 
01231         // build the link
01232 #ifdef HAVE_INTERNAL_LANES
01233         MSLane* via = 0;
01234         if (viaID != "" && MSGlobals::gUsingInternalLanes) {
01235             via = MSLane::dictionary(viaID);
01236             if (via == 0) {
01237                 WRITE_ERROR("An unknown lane ('" + viaID +
01238                             "') should be set as a via-lane for lane '" + toLane->getID() + "'.");
01239                 return;
01240             }
01241             length = via->getLength();
01242         }
01243         if (pass >= 0) {
01244             static_cast<MSInternalLane*>(toLane)->setPassPosition(pass);
01245         }
01246         link = new MSLink(toLane, via, dir, state, length);
01247         if (via != 0) {
01248             via->addIncomingLane(fromLane, link);
01249         } else {
01250             toLane->addIncomingLane(fromLane, link);
01251         }
01252 #else
01253         link = new MSLink(toLane, dir, state, length);
01254         toLane->addIncomingLane(fromLane, link);
01255 #endif
01256         toLane->addApproachingLane(fromLane);
01257 
01258         // if a traffic light is responsible for it, inform the traffic light
01259         // check whether this link is controlled by a traffic light
01260         if (tlID != "") {
01261             MSTLLogicControl::TLSLogicVariants& logics = myJunctionControlBuilder.getTLLogic(tlID);
01262             logics.addLink(link, fromLane, tlLinkIdx);
01263         }
01264         // add the link
01265         fromLane->addLink(link);
01266 
01267     } catch (InvalidArgument& e) {
01268         WRITE_ERROR(e.what());
01269     }
01270 }
01271 
01272 
01273 LinkDirection
01274 NLHandler::parseLinkDir(const std::string& dir) {
01275     if (SUMOXMLDefinitions::LinkDirections.hasString(dir)) {
01276         return SUMOXMLDefinitions::LinkDirections.get(dir);
01277     } else {
01278         throw InvalidArgument("Unrecognised link direction '" + dir + "'.");
01279     }
01280 }
01281 
01282 
01283 LinkState
01284 NLHandler::parseLinkState(const std::string& state) {
01285     if (SUMOXMLDefinitions::LinkStates.hasString(state)) {
01286         return SUMOXMLDefinitions::LinkStates.get(state);
01287     } else {
01288         if (state == "t") { // legacy networks
01289             // WRITE_WARNING("Obsolete link state 't'. Use 'o' instead");
01290             return LINKSTATE_TL_OFF_BLINKING;
01291         } else {
01292             throw InvalidArgument("Unrecognised link state '" + state + "'.");
01293         }
01294     }
01295 }
01296 
01297 
01298 std::pair<MSLane*, MSLane*>
01299 NLHandler::getLanesFromIndices(MSEdge* from, MSEdge* to, const std::string& laneIndices, bool& ok) {
01300     std::string error = "Invalid attribute in connection from '" + from->getID() + "' to '" + to->getID() + "' ";
01301     StringTokenizer st(laneIndices, ':');
01302     if (st.size() == 2) {
01303         int fromLaneIdx;
01304         int toLaneIdx;
01305         try {
01306             fromLaneIdx = TplConvertSec<char>::_2intSec(st.next().c_str(), -1);
01307             toLaneIdx = TplConvertSec<char>::_2intSec(st.next().c_str(), -1);
01308             if (fromLaneIdx >= 0 && static_cast<unsigned int>(fromLaneIdx) < from->getLanes().size() &&
01309                     toLaneIdx >= 0 && static_cast<unsigned int>(toLaneIdx) < to->getLanes().size()) {
01310                 return std::pair<MSLane*, MSLane*>(from->getLanes()[fromLaneIdx], to->getLanes()[toLaneIdx]);
01311             } else {
01312                 error += "(invalid index)";
01313             }
01314         } catch (NumberFormatException&) {
01315             error += "(number format)";
01316         }
01317     } else {
01318         error += "(malformed)";
01319     }
01320     WRITE_ERROR(error);
01321     ok = false;
01322     return std::pair<MSLane*, MSLane*>(static_cast<MSLane*>(0), static_cast<MSLane*>(0));
01323 }
01324 
01325 
01326 // ----------------------------------
01327 void
01328 NLHandler::setLocation(const SUMOSAXAttributes& attrs) {
01329     bool ok = true;
01330     PositionVector s = GeomConvHelper::parseShapeReporting(
01331                            attrs.getStringReporting(SUMO_ATTR_NET_OFFSET, 0, ok),
01332                            attrs.getObjectType(), 0, ok, false);
01333     Boundary convBoundary = GeomConvHelper::parseBoundaryReporting(
01334                                 attrs.getStringReporting(SUMO_ATTR_CONV_BOUNDARY, 0, ok),
01335                                 attrs.getObjectType(), 0, ok);
01336     Boundary origBoundary = GeomConvHelper::parseBoundaryReporting(
01337                                 attrs.getStringReporting(SUMO_ATTR_ORIG_BOUNDARY, 0, ok),
01338                                 attrs.getObjectType(), 0, ok);
01339     std::string proj = attrs.getStringReporting(SUMO_ATTR_ORIG_PROJ, 0, ok);
01340     if (ok) {
01341         Position networkOffset = s[0];
01342         GeoConvHelper::init(proj, networkOffset, origBoundary, convBoundary);
01343     }
01344 }
01345 
01346 
01347 void
01348 NLHandler::addDistrict(const SUMOSAXAttributes& attrs) {
01349     bool ok = true;
01350     myCurrentIsBroken = false;
01351     // get the id, report an error if not given or empty...
01352     myCurrentDistrictID = attrs.getStringReporting(SUMO_ATTR_ID, 0, ok);
01353     if (!ok) {
01354         myCurrentIsBroken = true;
01355         return;
01356     }
01357     try {
01358         MSEdge* sink = myEdgeControlBuilder.buildEdge(myCurrentDistrictID + "-sink");
01359         if (!MSEdge::dictionary(myCurrentDistrictID + "-sink", sink)) {
01360             delete sink;
01361             throw InvalidArgument("Another edge with the id '" + myCurrentDistrictID + "-sink' exists.");
01362         }
01363         sink->initialize(new std::vector<MSLane*>(), MSEdge::EDGEFUNCTION_DISTRICT);
01364         MSEdge* source = myEdgeControlBuilder.buildEdge(myCurrentDistrictID + "-source");
01365         if (!MSEdge::dictionary(myCurrentDistrictID + "-source", source)) {
01366             delete source;
01367             throw InvalidArgument("Another edge with the id '" + myCurrentDistrictID + "-source' exists.");
01368         }
01369         source->initialize(new std::vector<MSLane*>(), MSEdge::EDGEFUNCTION_DISTRICT);
01370         if (attrs.hasAttribute(SUMO_ATTR_EDGES)) {
01371             std::vector<std::string> desc = StringTokenizer(attrs.getString(SUMO_ATTR_EDGES)).getVector();
01372             for (std::vector<std::string>::const_iterator i = desc.begin(); i != desc.end(); ++i) {
01373                 MSEdge* edge = MSEdge::dictionary(*i);
01374                 // check whether the edge exists
01375                 if (edge == 0) {
01376                     throw InvalidArgument("The edge '" + *i + "' within district '" + myCurrentDistrictID + "' is not known.");
01377                 }
01378                 source->addFollower(edge);
01379                 edge->addFollower(sink);
01380             }
01381         }
01382     } catch (InvalidArgument& e) {
01383         WRITE_ERROR(e.what());
01384         myCurrentIsBroken = true;
01385     }
01386 }
01387 
01388 
01389 void
01390 NLHandler::addDistrictEdge(const SUMOSAXAttributes& attrs, bool isSource) {
01391     if (myCurrentIsBroken) {
01392         // earlier error
01393         return;
01394     }
01395     bool ok = true;
01396     std::string id = attrs.getStringReporting(SUMO_ATTR_ID, myCurrentDistrictID.c_str(), ok);
01397     MSEdge* succ = MSEdge::dictionary(id);
01398     if (succ != 0) {
01399         // connect edge
01400         if (isSource) {
01401             MSEdge::dictionary(myCurrentDistrictID + "-source")->addFollower(succ);
01402         } else {
01403             succ->addFollower(MSEdge::dictionary(myCurrentDistrictID + "-sink"));
01404         }
01405     } else {
01406         WRITE_ERROR("At district '" + myCurrentDistrictID + "': succeeding edge '" + id + "' does not exist.");
01407     }
01408 }
01409 
01410 
01411 // ----------------------------------
01412 
01413 
01414 void
01415 NLHandler::closeSuccLane() {
01416     // do not process internal lanes if not wished
01417     if (myCurrentIsInternalToSkip) {
01418         return;
01419     }
01420     try {
01421         mySucceedingLaneBuilder.closeSuccLane();
01422     } catch (InvalidArgument& e) {
01423         WRITE_ERROR(e.what());
01424     }
01425 }
01426 
01427 
01428 void
01429 NLHandler::endE3Detector() {
01430     try {
01431         myDetectorBuilder.endE3Detector();
01432     } catch (InvalidArgument& e) {
01433         WRITE_ERROR(e.what());
01434     }
01435 }
01436 
01437 
01438 void
01439 NLHandler::closeWAUT() {
01440     if (!myCurrentIsBroken) {
01441         try {
01442             myJunctionControlBuilder.getTLLogicControlToUse().closeWAUT(myCurrentWAUTID);
01443         } catch (InvalidArgument& e) {
01444             WRITE_ERROR(e.what());
01445             myCurrentIsBroken = true;
01446         }
01447     }
01448     myCurrentWAUTID = "";
01449 }
01450 
01451 
01452 /****************************************************************************/
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Friends Defines