NLHandler.cpp

Go to the documentation of this file.
00001 /****************************************************************************/
00007 // The XML-Handler for network loading
00008 /****************************************************************************/
00009 // SUMO, Simulation of Urban MObility; see http://sumo.sourceforge.net/
00010 // Copyright 2001-2010 DLR (http://www.dlr.de/) and contributors
00011 /****************************************************************************/
00012 //
00013 //   This program is free software; you can redistribute it and/or modify
00014 //   it under the terms of the GNU General Public License as published by
00015 //   the Free Software Foundation; either version 2 of the License, or
00016 //   (at your option) any later version.
00017 //
00018 /****************************************************************************/
00019 // ===========================================================================
00020 // included modules
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 // method definitions
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)); // !!! no error handling!
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 // ---- the root/edge - element
00349 void
00350 NLHandler::beginEdgeParsing(const SUMOSAXAttributes &attrs) {
00351     myCurrentIsBroken = false;
00352     // get the id, report an error if not given or empty...
00353     std::string id;
00354     if (!attrs.setIDFromAttributes("edge", id)) {
00355         myCurrentIsBroken = true;
00356         return;
00357     }
00358     // omit internal edges if not wished
00359     if (!MSGlobals::gUsingInternalLanes&&id[0]==':') {
00360         myCurrentIsInternalToSkip = true;
00361         return;
00362     }
00363     myCurrentIsInternalToSkip = false;
00364     // get the function
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     // parse the function
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     // omit internal edges if not wished and broken edges
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 //             ---- the root/edge/lanes/lane - element
00410 void
00411 NLHandler::addLane(const SUMOSAXAttributes &attrs) {
00412     myShape.clear();
00413     // omit internal edges if not wished and broken edges
00414     if (myCurrentIsInternalToSkip||myCurrentIsBroken) {
00415         return;
00416     }
00417     // get the id, report an error if not given or empty...
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     // omit internal edges if not wished and broken edges
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     // omit internal edges if not wished and broken edges
00462     if (myCurrentIsInternalToSkip||myCurrentIsBroken) {
00463         return;
00464     }
00465     // check shape
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     // build
00472     try {
00473         MSLane *lane =
00474             myEdgeControlBuilder.addLane(myCurrentLaneID, myCurrentMaxSpeed, myCurrentLength, myLaneIsDepart, myShape, myAllowedClasses, myDisallowedClasses);
00475         // insert the lane into the lane-dictionary, checking
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 // ---- the root/junction - element
00488 void
00489 NLHandler::openJunction(const SUMOSAXAttributes &attrs) {
00490     myCurrentIsBroken = false;
00491     // get the id, report an error if not given or empty...
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         // @deprecated: at some time, all junctions should have a shape attribute (moved from characters)
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     // set
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     // get the id, report an error if not given or empty...
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     // get the id, report an error if not given or empty...
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     // get the id, report an error if not given or empty...
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         // @deprecated; at some time, this is mandatory (no character usage)
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     // store received information
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         // @deprecated: assuming a net could still use characters for the id
00715         myJunctionControlBuilder.initJunctionLogic("", -1, -1);
00716         return;
00717     }
00718     // get the id, report an error if not given or empty...
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(); // @deprecated (is this still used?)
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         // @deprecated: assuming a net could still use characters for the id
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     // try to get the phase definition
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         // ok, doing it the new way
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         // check
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         // convert to new
00781         state = MSPhaseDefinition::old2new(phase, brakeMask, yellowMask);
00782     }
00783     if (!ok) {
00784         return;
00785     }
00786     // try to get the phase duration
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     // if the traffic light is an actuated traffic light, try to get
00793     //  the minimum and maximum durations
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     // if no file given, use stdout
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     // get the id, report an error if not given or empty...
00826     std::string id;
00827     if (!attrs.setIDFromAttributes("detector", id)) {
00828         return;
00829     }
00830     // try to get the type
00831     bool ok = true;
00832     std::string type = attrs.getOptStringReporting(SUMO_ATTR_TYPE, 0, 0, ok, "induct_loop");
00833     // build in dependence to type
00834     // induct loops (E1-detectors)
00835     if (type=="induct_loop"||type=="E1"||type=="e1") {
00836         addE1Detector(attrs);
00837         myCurrentDetectorType = "e1";
00838         return;
00839     }
00840     // lane-based areal detectors (E2-detectors)
00841     if (type=="lane_based"||type=="E2"||type=="e2") {
00842         addE2Detector(attrs);
00843         myCurrentDetectorType = "e2";
00844         return;
00845     }
00846     // multi-origin/multi-destination detectors (E3-detectors)
00847     if (type=="multi_od"||type=="E3"||type=="e3") {
00848         beginE3Detector(attrs);
00849         myCurrentDetectorType = "e3";
00850         return;
00851     }
00852 #ifdef _MESSAGES
00853     // new induct loop, for static messages
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     // get the id, report an error if not given or empty...
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     // get the id, report an error if not given or empty...
00893     std::string id;
00894     if (!attrs.setIDFromAttributes("e1-detector", id)) {
00895         return;
00896     }
00897     // inform the user about deprecated values
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     // get the id, report an error if not given or empty...
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     // get the id, report an error if not given or empty...
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     // get the id, report an error if not given or empty...
00976     std::string id;
00977     if (!attrs.setIDFromAttributes("e2-detector", id)) {
00978         return;
00979     }
00980     // check whether this is a detector connected to a tls an optionally to a link
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     // inform the user about deprecated values
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     // get the id, report an error if not given or empty...
01041     std::string id;
01042     if (!attrs.setIDFromAttributes("e3-detector", id)) {
01043         return;
01044     }
01045     bool ok = true;
01046     // inform the user about deprecated values
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     // get the id, report an error if not given or empty...
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     // get the id, report an error if not given or empty...
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     // get the id, report an error if not given or empty...
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     // do not process internal lanes if not wished
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     // @deprecated: assuming a net could still use characters for the request size
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     // @deprecated: assuming a net could still use characters for the lane number
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     // @deprecated: assuming a net could still use characters for the id
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     // @deprecated: assuming a net could still use characters for the sub id
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     // @deprecated: assuming a net could still use characters for the offset
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     } // !!! can chars have length 0?
01325 }
01326 
01327 
01328 void
01329 NLHandler::addJunctionShape(const std::string &chars) {
01330     // @deprecated: at some time, all junctions should have a shape attribute (moved from characters)
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     // get the id, report an error if not given or empty...
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                 // check whether the edge exists
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         // earlier error
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         // connect edge
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     // @deprecated: at some time, all junctions should have a shape attribute (moved from characters)
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     // @deprecated: at some time, all junctions should have a shape attribute (moved from characters)
01444     // do not parse internal lanes if not wished
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     // do not process internal lanes if not wished
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 /****************************************************************************/

Generated on Wed May 5 00:06:35 2010 for Sumo - Simulation of Urban MObility by  doxygen 1.5.6