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     SUMOVehicleClasses allowedClasses;
00474     SUMOVehicleClasses disallowedClasses;
00475     parseVehicleClasses(allow, disallow, allowedClasses, disallowedClasses);
00476     myCurrentIsBroken |= !ok;
00477     if (!myCurrentIsBroken) {
00478         try {
00479             MSLane* lane = myEdgeControlBuilder.addLane(id, maxSpeed, length, shape, width, allowedClasses, disallowedClasses);
00480             // insert the lane into the lane-dictionary, checking
00481             if (!MSLane::dictionary(id, lane)) {
00482                 delete lane;
00483                 WRITE_ERROR("Another lane with the id '" + id + "' exists.");
00484                 myCurrentIsBroken = true;
00485             }
00486         } catch (InvalidArgument& e) {
00487             WRITE_ERROR(e.what());
00488         }
00489     }
00490 }
00491 
00492 
00493 // ---- the root/junction - element
00494 void
00495 NLHandler::openJunction(const SUMOSAXAttributes& attrs) {
00496     myCurrentIsBroken = false;
00497     bool ok = true;
00498     // get the id, report an error if not given or empty...
00499     std::string id = attrs.getStringReporting(SUMO_ATTR_ID, 0, ok);
00500     if (!ok) {
00501         myCurrentIsBroken = true;
00502         return;
00503     }
00504     PositionVector shape;
00505     if (attrs.hasAttribute(SUMO_ATTR_SHAPE)) {
00506         // inner junctions have no shape
00507         shape = GeomConvHelper::parseShapeReporting(attrs.getStringSecure(SUMO_ATTR_SHAPE, ""), attrs.getObjectType(), id.c_str(), ok, true);
00508     }
00509     SUMOReal x = attrs.getSUMORealReporting(SUMO_ATTR_X, id.c_str(), ok);
00510     SUMOReal y = attrs.getSUMORealReporting(SUMO_ATTR_Y, id.c_str(), ok);
00511     std::string type = attrs.getStringReporting(SUMO_ATTR_TYPE, id.c_str(), ok);
00512     std::string key = attrs.getOptStringReporting(SUMO_ATTR_KEY, id.c_str(), ok, "");
00513     // incoming lanes
00514     std::vector<MSLane*> incomingLanes;
00515     parseLanes(id, attrs.getStringSecure(SUMO_ATTR_INCLANES, ""), incomingLanes, ok);
00516     // internal lanes
00517     std::vector<MSLane*> internalLanes;
00518 #ifdef HAVE_INTERNAL_LANES
00519     if (MSGlobals::gUsingInternalLanes) {
00520         parseLanes(id, attrs.getStringSecure(SUMO_ATTR_INTLANES, ""), internalLanes, ok);
00521     }
00522 #endif
00523     if (!ok) {
00524         myCurrentIsBroken = true;
00525     } else {
00526         try {
00527             myJunctionControlBuilder.openJunction(id, key, type, x, y, shape, incomingLanes, internalLanes);
00528         } catch (InvalidArgument& e) {
00529             WRITE_ERROR(e.what() + std::string("\n Can not build according junction."));
00530             myCurrentIsBroken = true;
00531         }
00532     }
00533 }
00534 
00535 
00536 void
00537 NLHandler::parseLanes(const std::string& junctionID,
00538                       const std::string& def, std::vector<MSLane*> &into, bool& ok) {
00539     StringTokenizer st(def);
00540     while (ok && st.hasNext()) {
00541         std::string laneID = st.next();
00542         MSLane* lane = MSLane::dictionary(laneID);
00543         if (!MSGlobals::gUsingInternalLanes && laneID[0] == ':') {
00544             continue;
00545         }
00546         if (lane == 0) {
00547             WRITE_ERROR("An unknown lane ('" + laneID + "') was tried to be set as incoming to junction '" + junctionID + "'.");
00548             ok = false;
00549             continue;
00550         }
00551         into.push_back(lane);
00552     }
00553 }
00554 // ----
00555 
00556 void
00557 NLHandler::addParam(const SUMOSAXAttributes& attrs) {
00558     bool ok = true;
00559     std::string key = attrs.getStringReporting(SUMO_ATTR_KEY, 0, ok);
00560     std::string val = attrs.getStringReporting(SUMO_ATTR_VALUE, 0, ok);
00561     // set
00562     if (ok && myAmInTLLogicMode) {
00563         assert(key != "");
00564         assert(val != "");
00565         myJunctionControlBuilder.addParam(key, val);
00566     }
00567 }
00568 
00569 
00570 void
00571 NLHandler::openWAUT(const SUMOSAXAttributes& attrs) {
00572     myCurrentIsBroken = false;
00573     bool ok = true;
00574     // get the id, report an error if not given or empty...
00575     std::string id = attrs.getStringReporting(SUMO_ATTR_ID, 0, ok);
00576     if (!ok) {
00577         myCurrentIsBroken = true;
00578         return;
00579     }
00580     SUMOTime t = attrs.getOptSUMOTimeReporting(SUMO_ATTR_REF_TIME, id.c_str(), ok, 0);
00581     std::string pro = attrs.getStringReporting(SUMO_ATTR_START_PROG, id.c_str(), ok);
00582     if (!ok) {
00583         myCurrentIsBroken = true;
00584     }
00585     if (!myCurrentIsBroken) {
00586         myCurrentWAUTID = id;
00587         try {
00588             myJunctionControlBuilder.getTLLogicControlToUse().addWAUT(t, id, pro);
00589         } catch (InvalidArgument& e) {
00590             WRITE_ERROR(e.what());
00591             myCurrentIsBroken = true;
00592         }
00593     }
00594 }
00595 
00596 
00597 void
00598 NLHandler::addWAUTSwitch(const SUMOSAXAttributes& attrs) {
00599     bool ok = true;
00600     SUMOTime t = attrs.getSUMOTimeReporting(SUMO_ATTR_TIME, myCurrentWAUTID.c_str(), ok);
00601     std::string to = attrs.getStringReporting(SUMO_ATTR_TO, myCurrentWAUTID.c_str(), ok);
00602     if (!ok) {
00603         myCurrentIsBroken = true;
00604     }
00605     if (!myCurrentIsBroken) {
00606         try {
00607             myJunctionControlBuilder.getTLLogicControlToUse().addWAUTSwitch(myCurrentWAUTID, t, to);
00608         } catch (InvalidArgument& e) {
00609             WRITE_ERROR(e.what());
00610             myCurrentIsBroken = true;
00611         }
00612     }
00613 }
00614 
00615 
00616 void
00617 NLHandler::addWAUTJunction(const SUMOSAXAttributes& attrs) {
00618     bool ok = true;
00619     std::string wautID = attrs.getStringReporting(SUMO_ATTR_WAUT_ID, 0, ok);
00620     std::string junctionID = attrs.getStringReporting(SUMO_ATTR_JUNCTION_ID, 0, ok);
00621     std::string procedure = attrs.getOptStringReporting(SUMO_ATTR_PROCEDURE, 0, ok, "");
00622     bool synchron = attrs.getOptBoolReporting(SUMO_ATTR_SYNCHRON, 0, ok, false);
00623     if (!ok) {
00624         myCurrentIsBroken = true;
00625     }
00626     try {
00627         if (!myCurrentIsBroken) {
00628             myJunctionControlBuilder.getTLLogicControlToUse().addWAUTJunction(wautID, junctionID, procedure, synchron);
00629         }
00630     } catch (InvalidArgument& e) {
00631         WRITE_ERROR(e.what());
00632         myCurrentIsBroken = true;
00633     }
00634 }
00635 
00636 
00637 
00638 
00639 
00640 
00641 
00642 void
00643 NLHandler::addPOI(const SUMOSAXAttributes& attrs) {
00644     bool ok = true;
00645     const SUMOReal INVALID_POSITION(-1000000);
00646     std::string id = attrs.getStringReporting(SUMO_ATTR_ID, 0, ok);
00647     SUMOReal x = attrs.getOptSUMORealReporting(SUMO_ATTR_X, id.c_str(), ok, INVALID_POSITION);
00648     SUMOReal y = attrs.getOptSUMORealReporting(SUMO_ATTR_Y, id.c_str(), ok, INVALID_POSITION);
00649     SUMOReal lanePos = attrs.getOptSUMORealReporting(SUMO_ATTR_POSITION, id.c_str(), ok, INVALID_POSITION);
00650     int layer = attrs.getOptIntReporting(SUMO_ATTR_LAYER, id.c_str(), ok, GLO_SHAPE);
00651     std::string type = attrs.getOptStringReporting(SUMO_ATTR_TYPE, id.c_str(), ok, "");
00652     std::string laneID = attrs.getOptStringReporting(SUMO_ATTR_LANE, id.c_str(), ok, "");
00653     std::string colorStr = attrs.getOptStringReporting(SUMO_ATTR_COLOR, id.c_str(), ok, "1,0,0");
00654     RGBColor color = RGBColor::parseColorReporting(colorStr, attrs.getObjectType(), id.c_str(), true, ok);
00655     if (!ok) {
00656         return;
00657     }
00658     Position pos(x, y);
00659     if (x == INVALID_POSITION || y == INVALID_POSITION) {
00660         MSLane* lane = MSLane::dictionary(laneID);
00661         if (lane == 0) {
00662             WRITE_ERROR("Lane '" + laneID + "' to place a poi '" + id + "'on is not known.");
00663             return;
00664         }
00665         if (lanePos < 0) {
00666             lanePos = lane->getLength() + lanePos;
00667         }
00668         pos = lane->getShape().positionAtLengthPosition(lanePos);
00669     }
00670     if (!myNet.getShapeContainer().addPoI(id, layer, type, color, pos)) {
00671         WRITE_ERROR("PoI '" + id + "' already exists.");
00672     }
00673 }
00674 
00675 
00676 void
00677 NLHandler::addPoly(const SUMOSAXAttributes& attrs) {
00678     bool ok = true;
00679     std::string id = attrs.getStringReporting(SUMO_ATTR_ID, 0, ok);
00680     // get the id, report an error if not given or empty...
00681     if (!ok) {
00682         return;
00683     }
00684     int layer = attrs.getOptIntReporting(SUMO_ATTR_LAYER, id.c_str(), ok, GLO_SHAPE);
00685     bool fill = attrs.getOptBoolReporting(SUMO_ATTR_FILL, id.c_str(), ok, false);
00686     std::string type = attrs.getOptStringReporting(SUMO_ATTR_TYPE, id.c_str(), ok, "");
00687     std::string colorStr = attrs.getStringReporting(SUMO_ATTR_COLOR, id.c_str(), ok);
00688     RGBColor color = RGBColor::parseColorReporting(colorStr, attrs.getObjectType(), id.c_str(), true, ok);
00689     PositionVector shape = GeomConvHelper::parseShapeReporting(attrs.getStringReporting(SUMO_ATTR_SHAPE, id.c_str(), ok), attrs.getObjectType(), id.c_str(), ok, false);
00690     if (shape.size() != 0) {
00691         if (!myNet.getShapeContainer().addPolygon(id, layer, type, color, fill, shape)) {
00692             WRITE_ERROR("Polygon '" + id + "' already exists.");
00693         }
00694     }
00695 }
00696 
00697 
00698 void
00699 NLHandler::addLogicItem(const SUMOSAXAttributes& attrs) {
00700     bool ok = true;
00701     int request = attrs.getIntReporting(SUMO_ATTR_REQUEST, 0, ok);
00702     bool cont = false;
00703 #ifdef HAVE_INTERNAL_LANES
00704     cont = attrs.getOptBoolReporting(SUMO_ATTR_CONT, 0, ok, false);
00705 #endif
00706     std::string response = attrs.getStringReporting(SUMO_ATTR_RESPONSE, 0, ok);
00707     std::string foes = attrs.getStringReporting(SUMO_ATTR_FOES, 0, ok);
00708     if (!ok) {
00709         return;
00710     }
00711     // store received information
00712     if (request >= 0 && response.length() > 0) {
00713         try {
00714             myJunctionControlBuilder.addLogicItem(request, response, foes, cont);
00715         } catch (InvalidArgument& e) {
00716             WRITE_ERROR(e.what());
00717         }
00718     }
00719 }
00720 
00721 
00722 void
00723 NLHandler::addRequest(const SUMOSAXAttributes& attrs) {
00724     if (myCurrentIsBroken) {
00725         return;
00726     }
00727     bool ok = true;
00728     int request = attrs.getIntReporting(SUMO_ATTR_INDEX, 0, ok);
00729     bool cont = false;
00730 #ifdef HAVE_INTERNAL_LANES
00731     cont = attrs.getOptBoolReporting(SUMO_ATTR_CONT, 0, ok, false);
00732 #endif
00733     std::string response = attrs.getStringReporting(SUMO_ATTR_RESPONSE, 0, ok);
00734     std::string foes = attrs.getStringReporting(SUMO_ATTR_FOES, 0, ok);
00735     if (!ok) {
00736         return;
00737     }
00738     // store received information
00739     if (request >= 0 && response.length() > 0) {
00740         try {
00741             myJunctionControlBuilder.addLogicItem(request, response, foes, cont);
00742         } catch (InvalidArgument& e) {
00743             WRITE_ERROR(e.what());
00744         }
00745     }
00746 }
00747 
00748 
00749 void
00750 NLHandler::initJunctionLogic(const SUMOSAXAttributes& attrs) {
00751     if (myCurrentIsBroken) {
00752         return;
00753     }
00754     bool ok = true;
00755     // we either a have a junction or a legacy network with ROWLogic
00756     std::string id = attrs.getStringReporting(SUMO_ATTR_ID, 0, ok);
00757     if (ok) {
00758         myJunctionControlBuilder.initJunctionLogic(id);
00759     }
00760 }
00761 
00762 
00763 void
00764 NLHandler::initTrafficLightLogic(const SUMOSAXAttributes& attrs) {
00765     myAmInTLLogicMode = true;
00766     bool ok = true;
00767     std::string id = attrs.getStringReporting(SUMO_ATTR_ID, 0, ok);
00768     TrafficLightType type;
00769     std::string typeS = attrs.getStringReporting(SUMO_ATTR_TYPE, 0, ok);
00770     if (SUMOXMLDefinitions::TrafficLightTypes.hasString(typeS)) {
00771         type = SUMOXMLDefinitions::TrafficLightTypes.get(typeS);
00772     } else {
00773         WRITE_ERROR("Traffic light '" + id + "' has unknown type '" + typeS + "'");
00774         return;
00775     }
00776     //
00777     SUMOTime offset = attrs.getOptSUMOTimeReporting(SUMO_ATTR_OFFSET, id.c_str(), ok, 0);
00778     if (!ok) {
00779         return;
00780     }
00781     std::string programID = attrs.getOptStringReporting(SUMO_ATTR_PROGRAMID, id.c_str(), ok, "<unknown>");
00782     myJunctionControlBuilder.initTrafficLightLogic(id, programID, type, offset);
00783 }
00784 
00785 
00786 void
00787 NLHandler::addPhase(const SUMOSAXAttributes& attrs) {
00788     // try to get the phase definition
00789     bool ok = true;
00790     std::string state = attrs.getStringReporting(SUMO_ATTR_STATE, 0, ok);
00791     if (!ok) {
00792         return;
00793     }
00794     // try to get the phase duration
00795     SUMOTime duration = attrs.getSUMOTimeReporting(SUMO_ATTR_DURATION, myJunctionControlBuilder.getActiveKey().c_str(), ok);
00796     if (duration == 0) {
00797         WRITE_ERROR("Duration of tls-logic '" + myJunctionControlBuilder.getActiveKey() + "/" + myJunctionControlBuilder.getActiveSubKey() + "' is zero.");
00798         return;
00799     }
00800     // if the traffic light is an actuated traffic light, try to get
00801     //  the minimum and maximum durations
00802     SUMOTime minDuration = -1;
00803     if (attrs.hasAttribute(SUMO_ATTR_MINDURATION__DEPRECATED)) {
00804         minDuration = attrs.getSUMOTimeReporting(SUMO_ATTR_MINDURATION__DEPRECATED, myJunctionControlBuilder.getActiveKey().c_str(), ok);
00805         if (!myHaveWarnedAboutDeprecatedTLSTiming) {
00806             myHaveWarnedAboutDeprecatedTLSTiming = true;
00807             WRITE_WARNING("Your tls definition contains deprecated minimum/maximum duration attribute; use minDur and maxDur instead.");
00808         }
00809     } else {
00810         minDuration = attrs.getOptSUMOTimeReporting(SUMO_ATTR_MINDURATION, myJunctionControlBuilder.getActiveKey().c_str(), ok, -1);
00811     }
00812     SUMOTime maxDuration = -1;
00813     if (attrs.hasAttribute(SUMO_ATTR_MAXDURATION__DEPRECATED)) {
00814         maxDuration = attrs.getSUMOTimeReporting(SUMO_ATTR_MAXDURATION__DEPRECATED, myJunctionControlBuilder.getActiveKey().c_str(), ok);
00815         if (!myHaveWarnedAboutDeprecatedTLSTiming) {
00816             myHaveWarnedAboutDeprecatedTLSTiming = true;
00817             WRITE_WARNING("Your tls definition contains deprecated minimum/maximum duration attribute; use minDur and maxDur instead.");
00818         }
00819     } else {
00820         maxDuration = attrs.getOptSUMOTimeReporting(SUMO_ATTR_MAXDURATION, myJunctionControlBuilder.getActiveKey().c_str(), ok, -1);
00821     }
00822     myJunctionControlBuilder.addPhase(duration, state, minDuration, maxDuration);
00823 }
00824 
00825 
00826 #ifdef _MESSAGES
00827 void
00828 NLHandler::addMsgEmitter(const SUMOSAXAttributes& attrs) {
00829     bool ok = true;
00830     std::string id = attrs.getStringReporting(SUMO_ATTR_ID, 0, ok);
00831     std::string file = attrs.getOptStringReporting(SUMO_ATTR_FILE, 0, ok, "");
00832     // if no file given, use stdout
00833     if (file == "") {
00834         file = "-";
00835     }
00836     SUMOTime step = attrs.getOptSUMOTimeReporting(SUMO_ATTR_STEP, id.c_str(), ok, 1);
00837     bool reverse = attrs.getOptBoolReporting(SUMO_ATTR_REVERSE, 0, ok, false);
00838     bool table = attrs.getOptBoolReporting(SUMO_ATTR_TABLE, 0, ok, false);
00839     bool xycoord = attrs.getOptBoolReporting(SUMO_ATTR_XY, 0, ok, false);
00840     std::string whatemit = attrs.getStringReporting(SUMO_ATTR_EVENTS, 0, ok);
00841     if (!ok) {
00842         return;
00843     }
00844     myNet.createMsgEmitter(id, file, getFileName(), whatemit, reverse, table, xycoord, step);
00845 }
00846 #endif
00847 
00848 
00849 void
00850 NLHandler::addE1Detector(const SUMOSAXAttributes& attrs) {
00851     bool ok = true;
00852     // get the id, report an error if not given or empty...
00853     std::string id = attrs.getStringReporting(SUMO_ATTR_ID, 0, ok);
00854     if (!ok) {
00855         return;
00856     }
00857     // inform the user about deprecated values
00858     SUMOTime frequency = attrs.getSUMOTimeReporting(SUMO_ATTR_FREQUENCY, id.c_str(), ok);
00859     SUMOReal position = attrs.getSUMORealReporting(SUMO_ATTR_POSITION, id.c_str(), ok);
00860     if (attrs.hasAttribute(SUMO_ATTR_FRIENDLY_POS__DEPRECATED) && !myHaveWarnedAboutDeprecatedFriendlyPos) {
00861         myHaveWarnedAboutDeprecatedFriendlyPos = true;
00862         WRITE_WARNING("'" + toString(SUMO_ATTR_FRIENDLY_POS__DEPRECATED) + "' is deprecated, use '" + toString(SUMO_ATTR_FRIENDLY_POS) + "' instead.");
00863     }
00864     bool friendlyPos = attrs.hasAttribute(SUMO_ATTR_FRIENDLY_POS__DEPRECATED)
00865                        ? attrs.getOptBoolReporting(SUMO_ATTR_FRIENDLY_POS__DEPRECATED, id.c_str(), ok, false)
00866                        : attrs.getOptBoolReporting(SUMO_ATTR_FRIENDLY_POS, id.c_str(), ok, false);
00867     bool splitByType = attrs.getOptBoolReporting(SUMO_ATTR_SPLIT_VTYPE, id.c_str(), ok, false);
00868     std::string lane = attrs.getStringReporting(SUMO_ATTR_LANE, id.c_str(), ok);
00869     std::string file = attrs.getStringReporting(SUMO_ATTR_FILE, id.c_str(), ok);
00870     if (!ok) {
00871         return;
00872     }
00873     try {
00874         myDetectorBuilder.buildInductLoop(id, lane, position, frequency,
00875                                           OutputDevice::getDevice(file, getFileName()),
00876                                           friendlyPos, splitByType);
00877     } catch (InvalidArgument& e) {
00878         WRITE_ERROR(e.what());
00879     } catch (IOError& e) {
00880         WRITE_ERROR(e.what());
00881     }
00882 }
00883 
00884 
00885 void
00886 NLHandler::addInstantE1Detector(const SUMOSAXAttributes& attrs) {
00887     bool ok = true;
00888     // get the id, report an error if not given or empty...
00889     std::string id = attrs.getStringReporting(SUMO_ATTR_ID, 0, ok);
00890     if (!ok) {
00891         return;
00892     }
00893     // inform the user about deprecated values
00894     SUMOReal position = attrs.getSUMORealReporting(SUMO_ATTR_POSITION, id.c_str(), ok);
00895     if (attrs.hasAttribute(SUMO_ATTR_FRIENDLY_POS__DEPRECATED) && !myHaveWarnedAboutDeprecatedFriendlyPos) {
00896         myHaveWarnedAboutDeprecatedFriendlyPos = true;
00897         WRITE_WARNING("'" + toString(SUMO_ATTR_FRIENDLY_POS__DEPRECATED) + "' is deprecated, use '" + toString(SUMO_ATTR_FRIENDLY_POS) + "' instead.");
00898     }
00899     bool friendlyPos = attrs.hasAttribute(SUMO_ATTR_FRIENDLY_POS__DEPRECATED)
00900                        ? attrs.getOptBoolReporting(SUMO_ATTR_FRIENDLY_POS__DEPRECATED, id.c_str(), ok, false)
00901                        : attrs.getOptBoolReporting(SUMO_ATTR_FRIENDLY_POS, id.c_str(), ok, false);
00902     std::string lane = attrs.getStringReporting(SUMO_ATTR_LANE, id.c_str(), ok);
00903     std::string file = attrs.getStringReporting(SUMO_ATTR_FILE, id.c_str(), ok);
00904     if (!ok) {
00905         return;
00906     }
00907     try {
00908         myDetectorBuilder.buildInstantInductLoop(id, lane, position, OutputDevice::getDevice(file, getFileName()), friendlyPos);
00909     } catch (InvalidArgument& e) {
00910         WRITE_ERROR(e.what());
00911     } catch (IOError& e) {
00912         WRITE_ERROR(e.what());
00913     }
00914 }
00915 
00916 
00917 void
00918 NLHandler::addVTypeProbeDetector(const SUMOSAXAttributes& attrs) {
00919     bool ok = true;
00920     std::string id = attrs.getStringReporting(SUMO_ATTR_ID, 0, ok);
00921     SUMOTime frequency = attrs.getSUMOTimeReporting(SUMO_ATTR_FREQUENCY, id.c_str(), ok);
00922     std::string type = attrs.getStringSecure(SUMO_ATTR_TYPE, "");
00923     std::string file = attrs.getStringReporting(SUMO_ATTR_FILE, id.c_str(), ok);
00924     if (!ok) {
00925         return;
00926     }
00927     try {
00928         myDetectorBuilder.buildVTypeProbe(id, type, frequency, OutputDevice::getDevice(file, getFileName()));
00929     } catch (InvalidArgument& e) {
00930         WRITE_ERROR(e.what());
00931     } catch (IOError& e) {
00932         WRITE_ERROR(e.what());
00933     }
00934 }
00935 
00936 
00937 void
00938 NLHandler::addRouteProbeDetector(const SUMOSAXAttributes& attrs) {
00939     bool ok = true;
00940     std::string id = attrs.getStringReporting(SUMO_ATTR_ID, 0, ok);
00941     SUMOTime frequency = attrs.getSUMOTimeReporting(SUMO_ATTR_FREQUENCY, id.c_str(), ok);
00942     SUMOTime begin = attrs.getOptSUMOTimeReporting(SUMO_ATTR_BEGIN, id.c_str(), ok, -1);
00943     std::string edge = attrs.getStringReporting(SUMO_ATTR_EDGE, id.c_str(), ok);
00944     std::string file = attrs.getStringReporting(SUMO_ATTR_FILE, id.c_str(), ok);
00945     if (!ok) {
00946         return;
00947     }
00948     try {
00949         myDetectorBuilder.buildRouteProbe(id, edge, frequency, begin,
00950                                           OutputDevice::getDevice(file, getFileName()));
00951     } catch (InvalidArgument& e) {
00952         WRITE_ERROR(e.what());
00953     } catch (IOError& e) {
00954         WRITE_ERROR(e.what());
00955     }
00956 }
00957 
00958 
00959 
00960 void
00961 NLHandler::addE2Detector(const SUMOSAXAttributes& attrs) {
00962     // check whether this is a detector connected to a tls an optionally to a link
00963     bool ok = true;
00964     std::string id = attrs.getStringReporting(SUMO_ATTR_ID, 0, ok);
00965     std::string lsaid = attrs.getOptStringReporting(SUMO_ATTR_TLID, id.c_str(), ok, "<invalid>");
00966     std::string toLane = attrs.getOptStringReporting(SUMO_ATTR_TO, id.c_str(), ok, "<invalid>");
00967     //
00968     if (attrs.hasAttribute(SUMO_ATTR_HALTING_TIME_THRESHOLD__DEPRECATED)) {
00969         myHaveWarnedAboutDeprecatedTimeThreshold = true;
00970         WRITE_WARNING("'" + toString(SUMO_ATTR_HALTING_TIME_THRESHOLD__DEPRECATED) + "' is deprecated; please use '" + toString(SUMO_ATTR_HALTING_TIME_THRESHOLD) + "'.");
00971     }
00972     if (attrs.hasAttribute(SUMO_ATTR_HALTING_SPEED_THRESHOLD__DEPRECATED)) {
00973         myHaveWarnedAboutDeprecatedSpeedThreshold = true;
00974         WRITE_WARNING("'" + toString(SUMO_ATTR_HALTING_SPEED_THRESHOLD__DEPRECATED) + "' is deprecated; please use '" + toString(SUMO_ATTR_HALTING_SPEED_THRESHOLD) + "'.");
00975     }
00976     if (attrs.hasAttribute(SUMO_ATTR_JAM_DIST_THRESHOLD__DEPRECATED)) {
00977         myHaveWarnedAboutDeprecatedJamDistThreshold = true;
00978         WRITE_WARNING("'" + toString(SUMO_ATTR_JAM_DIST_THRESHOLD__DEPRECATED) + "' is deprecated; please use '" + toString(SUMO_ATTR_JAM_DIST_THRESHOLD) + "'.");
00979     }
00980     if (attrs.hasAttribute(SUMO_ATTR_FRIENDLY_POS__DEPRECATED) && !myHaveWarnedAboutDeprecatedFriendlyPos) {
00981         myHaveWarnedAboutDeprecatedFriendlyPos = true;
00982         WRITE_WARNING("'" + toString(SUMO_ATTR_FRIENDLY_POS__DEPRECATED) + "' is deprecated; please use '" + toString(SUMO_ATTR_FRIENDLY_POS) + "'.");
00983     }
00984 
00985     const SUMOTime haltingTimeThreshold = attrs.hasAttribute(SUMO_ATTR_HALTING_TIME_THRESHOLD__DEPRECATED)
00986                                           ? attrs.getOptSUMOTimeReporting(SUMO_ATTR_HALTING_TIME_THRESHOLD__DEPRECATED, id.c_str(), ok, TIME2STEPS(1))
00987                                           : attrs.getOptSUMOTimeReporting(SUMO_ATTR_HALTING_TIME_THRESHOLD, id.c_str(), ok, TIME2STEPS(1));
00988     const SUMOReal haltingSpeedThreshold = attrs.hasAttribute(SUMO_ATTR_HALTING_SPEED_THRESHOLD__DEPRECATED)
00989                                            ? attrs.getOptSUMORealReporting(SUMO_ATTR_HALTING_SPEED_THRESHOLD__DEPRECATED, id.c_str(), ok, 5.0f / 3.6f)
00990                                            : attrs.getOptSUMORealReporting(SUMO_ATTR_HALTING_SPEED_THRESHOLD, id.c_str(), ok, 5.0f / 3.6f);
00991     const SUMOReal jamDistThreshold = attrs.hasAttribute(SUMO_ATTR_JAM_DIST_THRESHOLD__DEPRECATED)
00992                                       ? attrs.getOptSUMORealReporting(SUMO_ATTR_JAM_DIST_THRESHOLD__DEPRECATED, id.c_str(), ok, 10.0f)
00993                                       : attrs.getOptSUMORealReporting(SUMO_ATTR_JAM_DIST_THRESHOLD, id.c_str(), ok, 10.0f);
00994     const SUMOReal position = attrs.getSUMORealReporting(SUMO_ATTR_POSITION, id.c_str(), ok);
00995     const SUMOReal length = attrs.getSUMORealReporting(SUMO_ATTR_LENGTH, id.c_str(), ok);
00996     const bool friendlyPos = attrs.hasAttribute(SUMO_ATTR_FRIENDLY_POS__DEPRECATED)
00997                              ? attrs.getOptBoolReporting(SUMO_ATTR_FRIENDLY_POS__DEPRECATED, id.c_str(), ok, false)
00998                              : attrs.getOptBoolReporting(SUMO_ATTR_FRIENDLY_POS, id.c_str(), ok, false);
00999     const bool cont = attrs.getOptBoolReporting(SUMO_ATTR_CONT, id.c_str(), ok, false);
01000     const std::string lane = attrs.getStringReporting(SUMO_ATTR_LANE, id.c_str(), ok);
01001     const std::string file = attrs.getStringReporting(SUMO_ATTR_FILE, id.c_str(), ok);
01002     if (!ok) {
01003         return;
01004     }
01005     try {
01006         if (lsaid != "<invalid>") {
01007             if (toLane == "<invalid>") {
01008                 myDetectorBuilder.buildE2Detector(id, lane, position, length, cont,
01009                                                   myJunctionControlBuilder.getTLLogic(lsaid),
01010                                                   OutputDevice::getDevice(file, getFileName()),
01011                                                   haltingTimeThreshold, haltingSpeedThreshold, jamDistThreshold,
01012                                                   friendlyPos);
01013             } else {
01014                 myDetectorBuilder.buildE2Detector(id, lane, position, length, cont,
01015                                                   myJunctionControlBuilder.getTLLogic(lsaid), toLane,
01016                                                   OutputDevice::getDevice(file, getFileName()),
01017                                                   haltingTimeThreshold, haltingSpeedThreshold, jamDistThreshold,
01018                                                   friendlyPos);
01019             }
01020         } else {
01021             bool ok = true;
01022             SUMOTime frequency = attrs.getSUMOTimeReporting(SUMO_ATTR_FREQUENCY, id.c_str(), ok);
01023             if (!ok) {
01024                 return;
01025             }
01026             myDetectorBuilder.buildE2Detector(id, lane, position, length, cont, frequency,
01027                                               OutputDevice::getDevice(file, getFileName()),
01028                                               haltingTimeThreshold, haltingSpeedThreshold, jamDistThreshold,
01029                                               friendlyPos);
01030         }
01031     } catch (InvalidArgument& e) {
01032         WRITE_ERROR(e.what());
01033     } catch (IOError& e) {
01034         WRITE_ERROR(e.what());
01035     }
01036 }
01037 
01038 
01039 void
01040 NLHandler::beginE3Detector(const SUMOSAXAttributes& attrs) {
01041     bool ok = true;
01042     // inform the user about deprecated values
01043     std::string id = attrs.getStringReporting(SUMO_ATTR_ID, 0, ok);
01044     if (attrs.hasAttribute(SUMO_ATTR_HALTING_TIME_THRESHOLD__DEPRECATED)) {
01045         myHaveWarnedAboutDeprecatedTimeThreshold = true;
01046         WRITE_WARNING("'" + toString(SUMO_ATTR_HALTING_TIME_THRESHOLD__DEPRECATED) + "' is deprecated; please use '" + toString(SUMO_ATTR_HALTING_TIME_THRESHOLD) + "'.");
01047     }
01048     if (attrs.hasAttribute(SUMO_ATTR_HALTING_SPEED_THRESHOLD__DEPRECATED)) {
01049         myHaveWarnedAboutDeprecatedSpeedThreshold = true;
01050         WRITE_WARNING("'" + toString(SUMO_ATTR_HALTING_SPEED_THRESHOLD__DEPRECATED) + "' is deprecated; please use '" + toString(SUMO_ATTR_HALTING_SPEED_THRESHOLD) + "'.");
01051     }
01052 
01053     const SUMOTime frequency = attrs.getSUMOTimeReporting(SUMO_ATTR_FREQUENCY, id.c_str(), ok);
01054     const SUMOTime haltingTimeThreshold = attrs.hasAttribute(SUMO_ATTR_HALTING_TIME_THRESHOLD__DEPRECATED)
01055                                           ? attrs.getOptSUMOTimeReporting(SUMO_ATTR_HALTING_TIME_THRESHOLD__DEPRECATED, id.c_str(), ok, TIME2STEPS(1))
01056                                           : attrs.getOptSUMOTimeReporting(SUMO_ATTR_HALTING_TIME_THRESHOLD, id.c_str(), ok, TIME2STEPS(1));
01057     const SUMOReal haltingSpeedThreshold = attrs.hasAttribute(SUMO_ATTR_HALTING_SPEED_THRESHOLD__DEPRECATED)
01058                                            ? attrs.getOptSUMORealReporting(SUMO_ATTR_HALTING_SPEED_THRESHOLD__DEPRECATED, id.c_str(), ok, 5.0f / 3.6f)
01059                                            : attrs.getOptSUMORealReporting(SUMO_ATTR_HALTING_SPEED_THRESHOLD, id.c_str(), ok, 5.0f / 3.6f);
01060     const std::string file = attrs.getStringReporting(SUMO_ATTR_FILE, id.c_str(), ok);
01061     if (!ok) {
01062         return;
01063     }
01064     try {
01065         myDetectorBuilder.beginE3Detector(id,
01066                                           OutputDevice::getDevice(file, getFileName()),
01067                                           frequency, haltingSpeedThreshold, haltingTimeThreshold);
01068     } catch (InvalidArgument& e) {
01069         WRITE_ERROR(e.what());
01070     } catch (IOError& e) {
01071         WRITE_ERROR(e.what());
01072     }
01073 }
01074 
01075 
01076 void
01077 NLHandler::addE3Entry(const SUMOSAXAttributes& attrs) {
01078     bool ok = true;
01079     if (attrs.hasAttribute(SUMO_ATTR_FRIENDLY_POS__DEPRECATED) && !myHaveWarnedAboutDeprecatedFriendlyPos) {
01080         myHaveWarnedAboutDeprecatedFriendlyPos = true;
01081         WRITE_WARNING("'" + toString(SUMO_ATTR_FRIENDLY_POS__DEPRECATED) + "' is deprecated, use '" + toString(SUMO_ATTR_FRIENDLY_POS) + "' instead.");
01082     }
01083     const SUMOReal position = attrs.getSUMORealReporting(SUMO_ATTR_POSITION, myDetectorBuilder.getCurrentE3ID().c_str(), ok);
01084     const bool friendlyPos = attrs.hasAttribute(SUMO_ATTR_FRIENDLY_POS__DEPRECATED)
01085                              ? attrs.getOptBoolReporting(SUMO_ATTR_FRIENDLY_POS__DEPRECATED, myDetectorBuilder.getCurrentE3ID().c_str(), ok, false)
01086                              : attrs.getOptBoolReporting(SUMO_ATTR_FRIENDLY_POS, myDetectorBuilder.getCurrentE3ID().c_str(), ok, false);
01087     const std::string lane = attrs.getStringReporting(SUMO_ATTR_LANE, myDetectorBuilder.getCurrentE3ID().c_str(), ok);
01088     if (!ok) {
01089         return;
01090     }
01091     myDetectorBuilder.addE3Entry(lane, position, friendlyPos);
01092 }
01093 
01094 
01095 void
01096 NLHandler::addE3Exit(const SUMOSAXAttributes& attrs) {
01097     bool ok = true;
01098     const SUMOReal position = attrs.getSUMORealReporting(SUMO_ATTR_POSITION, myDetectorBuilder.getCurrentE3ID().c_str(), ok);
01099     if (attrs.hasAttribute(SUMO_ATTR_FRIENDLY_POS__DEPRECATED) && !myHaveWarnedAboutDeprecatedFriendlyPos) {
01100         myHaveWarnedAboutDeprecatedFriendlyPos = true;
01101         WRITE_WARNING("'" + toString(SUMO_ATTR_FRIENDLY_POS__DEPRECATED) + "' is deprecated, use '" + toString(SUMO_ATTR_FRIENDLY_POS) + "' instead.");
01102     }
01103     const bool friendlyPos = attrs.hasAttribute(SUMO_ATTR_FRIENDLY_POS__DEPRECATED)
01104                              ? attrs.getOptBoolReporting(SUMO_ATTR_FRIENDLY_POS__DEPRECATED, myDetectorBuilder.getCurrentE3ID().c_str(), ok, false)
01105                              : attrs.getOptBoolReporting(SUMO_ATTR_FRIENDLY_POS, myDetectorBuilder.getCurrentE3ID().c_str(), ok, false);
01106     const std::string lane = attrs.getStringReporting(SUMO_ATTR_LANE, myDetectorBuilder.getCurrentE3ID().c_str(), ok);
01107     if (!ok) {
01108         return;
01109     }
01110     myDetectorBuilder.addE3Exit(lane, position, friendlyPos);
01111 }
01112 
01113 
01114 void
01115 NLHandler::addEdgeLaneMeanData(const SUMOSAXAttributes& attrs, int objecttype) {
01116     bool ok = true;
01117     std::string id = attrs.getStringReporting(SUMO_ATTR_ID, 0, ok);
01118     const SUMOReal maxTravelTime = attrs.getOptSUMORealReporting(SUMO_ATTR_MAX_TRAVELTIME, id.c_str(), ok, 100000);
01119     const SUMOReal minSamples = attrs.getOptSUMORealReporting(SUMO_ATTR_MIN_SAMPLES, id.c_str(), ok, 0);
01120     const SUMOReal haltingSpeedThreshold = attrs.getOptSUMORealReporting(SUMO_ATTR_HALTING_SPEED_THRESHOLD, id.c_str(), ok, POSITION_EPS);
01121     const bool excludeEmpty = attrs.getOptBoolReporting(SUMO_ATTR_EXCLUDE_EMPTY, id.c_str(), ok, false);
01122     const bool withInternal = attrs.getOptBoolReporting(SUMO_ATTR_WITH_INTERNAL, id.c_str(), ok, false);
01123     const bool trackVehicles = attrs.getOptBoolReporting(SUMO_ATTR_TRACK_VEHICLES, id.c_str(), ok, false);
01124     const std::string file = attrs.getStringReporting(SUMO_ATTR_FILE, id.c_str(), ok);
01125     const std::string type = attrs.getOptStringReporting(SUMO_ATTR_TYPE, id.c_str(), ok, "performance");
01126     std::string vtypes = attrs.getOptStringReporting(SUMO_ATTR_VTYPES, id.c_str(), ok, "");
01127     if (attrs.hasAttribute(SUMO_ATTR_VTYPES__DEPRECATED)) {
01128         vtypes = attrs.getStringReporting(SUMO_ATTR_VTYPES__DEPRECATED, id.c_str(), ok);
01129         if (!myHaveWarnedAboutDeprecatedVTypes) {
01130             WRITE_WARNING("'" + toString(SUMO_ATTR_VTYPES__DEPRECATED) + " is deprecated; please use '" + toString(SUMO_ATTR_VTYPES) + "'.");
01131             myHaveWarnedAboutDeprecatedVTypes = true;
01132         }
01133     }
01134     const SUMOTime frequency = attrs.getOptSUMOTimeReporting(SUMO_ATTR_FREQUENCY, id.c_str(), ok, -1);
01135     const SUMOTime begin = attrs.getOptSUMOTimeReporting(SUMO_ATTR_BEGIN, id.c_str(), ok, string2time(OptionsCont::getOptions().getString("begin")));
01136     const SUMOTime end = attrs.getOptSUMOTimeReporting(SUMO_ATTR_END, id.c_str(), ok, string2time(OptionsCont::getOptions().getString("end")));
01137     if (!ok) {
01138         return;
01139     }
01140     try {
01141         myDetectorBuilder.createEdgeLaneMeanData(id, frequency, begin, end,
01142                 type, objecttype == SUMO_TAG_MEANDATA_LANE, !excludeEmpty, withInternal, trackVehicles,
01143                 maxTravelTime, minSamples, haltingSpeedThreshold, vtypes,
01144                 OutputDevice::getDevice(file, getFileName()));
01145     } catch (InvalidArgument& e) {
01146         WRITE_ERROR(e.what());
01147     } catch (IOError& e) {
01148         WRITE_ERROR(e.what());
01149     }
01150 }
01151 
01152 
01153 
01154 void
01155 NLHandler::openSucc(const SUMOSAXAttributes& attrs) {
01156     bool ok = true;
01157     std::string id = attrs.getStringReporting(SUMO_ATTR_LANE, 0, ok);
01158     if (!MSGlobals::gUsingInternalLanes && id[0] == ':') {
01159         myCurrentIsInternalToSkip = true;
01160         return;
01161     }
01162     myCurrentIsInternalToSkip = false;
01163     mySucceedingLaneBuilder.openSuccLane(id);
01164 }
01165 
01166 
01167 void
01168 NLHandler::addSuccLane(const SUMOSAXAttributes& attrs) {
01169     // do not process internal lanes if not wished
01170     if (myCurrentIsInternalToSkip) {
01171         return;
01172     }
01173     try {
01174         bool ok = true;
01175         SUMOReal pass = attrs.getOptSUMORealReporting(SUMO_ATTR_PASS, 0, ok, -1);
01176         std::string lane = attrs.getStringReporting(SUMO_ATTR_LANE, 0, ok);
01177         std::string dir = attrs.getStringReporting(SUMO_ATTR_DIR, 0, ok);
01178         std::string state = attrs.getStringReporting(SUMO_ATTR_STATE, 0, ok);
01179         std::string tlID = attrs.getOptStringReporting(SUMO_ATTR_TLID, 0, ok, "");
01180 #ifdef HAVE_INTERNAL_LANES
01181         std::string via = attrs.getOptStringReporting(SUMO_ATTR_VIA, 0, ok, "");
01182 #endif
01183         if (!ok) {
01184             return;
01185         }
01186         if (tlID != "") {
01187             int linkNumber = attrs.hasAttribute(SUMO_ATTR_TLLINKINDEX)
01188                              ? attrs.getIntReporting(SUMO_ATTR_TLLINKINDEX, 0, ok)
01189                              : attrs.getIntReporting(SUMO_ATTR_TLLINKNO__DEPRECATED, 0, ok);
01190             if (!ok) {
01191                 return;
01192             }
01193             mySucceedingLaneBuilder.addSuccLane(lane,
01194 #ifdef HAVE_INTERNAL_LANES
01195                                                 via, pass,
01196 #endif
01197                                                 parseLinkDir(dir), parseLinkState(state), tlID, linkNumber);
01198         } else {
01199             mySucceedingLaneBuilder.addSuccLane(lane,
01200 #ifdef HAVE_INTERNAL_LANES
01201                                                 via, pass,
01202 #endif
01203                                                 parseLinkDir(dir), parseLinkState(state));
01204         }
01205     } catch (InvalidArgument& e) {
01206         WRITE_ERROR(e.what());
01207     }
01208 }
01209 
01210 
01211 
01212 void
01213 NLHandler::addConnection(const SUMOSAXAttributes& attrs) {
01214     bool ok = true;
01215     std::string fromID = attrs.getStringReporting(SUMO_ATTR_FROM, 0, ok);
01216     if (!MSGlobals::gUsingInternalLanes && fromID[0] == ':') {
01217         return;
01218     }
01219 
01220     try {
01221         bool ok = true;
01222         std::string toID = attrs.getStringReporting(SUMO_ATTR_TO, 0, ok);
01223         std::string laneIndices;
01224         if (attrs.hasAttribute(SUMO_ATTR_LANE)) {
01225             if (!myHaveWarnedAboutDeprecatedLanes) {
01226                 myHaveWarnedAboutDeprecatedLanes = true;
01227                 WRITE_WARNING("'" + toString(SUMO_ATTR_LANE) + "' is deprecated, please use '" + toString(SUMO_ATTR_FROM_LANE) +
01228                               "' and '" + toString(SUMO_ATTR_TO_LANE) + "' instead.");
01229             }
01230             laneIndices = attrs.getStringReporting(SUMO_ATTR_LANE, 0, ok);
01231         } else {
01232             laneIndices = attrs.getStringReporting(SUMO_ATTR_FROM_LANE, 0, ok) + ":" + attrs.getStringReporting(SUMO_ATTR_TO_LANE, 0, ok);
01233         }
01234         LinkDirection dir = parseLinkDir(attrs.getStringReporting(SUMO_ATTR_DIR, 0, ok));
01235         LinkState state = parseLinkState(attrs.getStringReporting(SUMO_ATTR_STATE, 0, ok));
01236         std::string tlID = attrs.getOptStringReporting(SUMO_ATTR_TLID, 0, ok, "");
01237 #ifdef HAVE_INTERNAL_LANES
01238         std::string viaID = attrs.getOptStringReporting(SUMO_ATTR_VIA, 0, ok, "");
01239         SUMOReal pass = attrs.getOptSUMORealReporting(SUMO_ATTR_PASS, 0, ok, -1);
01240 #endif
01241 
01242         MSEdge* from = MSEdge::dictionary(fromID);
01243         if (from == 0) {
01244             WRITE_ERROR("Unknown from-edge '" + fromID + "' in connection");
01245             return;
01246         }
01247         MSEdge* to = MSEdge::dictionary(toID);
01248         if (to == 0) {
01249             WRITE_ERROR("Unknown to-edge '" + toID + "' in connection");
01250             return;
01251         }
01252         std::pair<MSLane*, MSLane*> lanes = getLanesFromIndices(from, to, laneIndices, ok);
01253         if (!ok) {
01254             return;
01255         }
01256         MSLane* fromLane = lanes.first;
01257         MSLane* toLane = lanes.second;
01258         assert(fromLane);
01259         assert(toLane);
01260 
01261         int tlLinkIdx;
01262         if (tlID != "") {
01263             tlLinkIdx = attrs.hasAttribute(SUMO_ATTR_TLLINKINDEX)
01264                         ? attrs.getIntReporting(SUMO_ATTR_TLLINKINDEX, 0, ok)
01265                         : attrs.getIntReporting(SUMO_ATTR_TLLINKNO__DEPRECATED, 0, ok);
01266             // make sure that the index is in range
01267             MSTrafficLightLogic* logic = myJunctionControlBuilder.getTLLogic(tlID).getActive();
01268             if (tlLinkIdx >= (int)logic->getCurrentPhaseDef().getState().size()) {
01269                 WRITE_ERROR("Invalid " + toString(SUMO_ATTR_TLLINKINDEX) + " '" + toString(tlLinkIdx) +
01270                             "' in connection controlled by '" + tlID + "'");
01271                 return;
01272             }
01273             if (!ok) {
01274                 return;
01275             }
01276         }
01277         SUMOReal length = fromLane->getShape()[-1].distanceTo(toLane->getShape()[0]);
01278         MSLink* link = 0;
01279 
01280         // build the link
01281 #ifdef HAVE_INTERNAL_LANES
01282         MSLane* via = 0;
01283         if (viaID != "" && MSGlobals::gUsingInternalLanes) {
01284             via = MSLane::dictionary(viaID);
01285             if (via == 0) {
01286                 WRITE_ERROR("An unknown lane ('" + viaID +
01287                             "') should be set as a via-lane for lane '" + toLane->getID() + "'.");
01288                 return;
01289             }
01290             length = via->getLength();
01291         }
01292         if (pass >= 0) {
01293             static_cast<MSInternalLane*>(toLane)->setPassPosition(pass);
01294         }
01295         link = new MSLink(toLane, via, dir, state, length);
01296         if (via != 0) {
01297             via->addIncomingLane(fromLane, link);
01298         } else {
01299             toLane->addIncomingLane(fromLane, link);
01300         }
01301 #else
01302         link = new MSLink(toLane, dir, state, length);
01303         toLane->addIncomingLane(fromLane, link);
01304 #endif
01305         toLane->addApproachingLane(fromLane);
01306 
01307         // if a traffic light is responsible for it, inform the traffic light
01308         // check whether this link is controlled by a traffic light
01309         if (tlID != "") {
01310             MSTLLogicControl::TLSLogicVariants& logics = myJunctionControlBuilder.getTLLogic(tlID);
01311             logics.addLink(link, fromLane, tlLinkIdx);
01312         }
01313         // add the link
01314         fromLane->addLink(link);
01315 
01316     } catch (InvalidArgument& e) {
01317         WRITE_ERROR(e.what());
01318     }
01319 }
01320 
01321 
01322 LinkDirection
01323 NLHandler::parseLinkDir(const std::string& dir) {
01324     if (SUMOXMLDefinitions::LinkDirections.hasString(dir)) {
01325         return SUMOXMLDefinitions::LinkDirections.get(dir);
01326     } else {
01327         throw InvalidArgument("Unrecognised link direction '" + dir + "'.");
01328     }
01329 }
01330 
01331 
01332 LinkState
01333 NLHandler::parseLinkState(const std::string& state) {
01334     if (SUMOXMLDefinitions::LinkStates.hasString(state)) {
01335         return SUMOXMLDefinitions::LinkStates.get(state);
01336     } else {
01337         if (state == "t") { // legacy networks
01338             // WRITE_WARNING("Obsolete link state 't'. Use 'o' instead");
01339             return LINKSTATE_TL_OFF_BLINKING;
01340         } else {
01341             throw InvalidArgument("Unrecognised link state '" + state + "'.");
01342         }
01343     }
01344 }
01345 
01346 
01347 std::pair<MSLane*, MSLane*>
01348 NLHandler::getLanesFromIndices(MSEdge* from, MSEdge* to, const std::string& laneIndices, bool& ok) {
01349     std::string error = "Invalid attribute in connection from '" + from->getID() + "' to '" + to->getID() + "' ";
01350     StringTokenizer st(laneIndices, ':');
01351     if (st.size() == 2) {
01352         int fromLaneIdx;
01353         int toLaneIdx;
01354         try {
01355             fromLaneIdx = TplConvertSec<char>::_2intSec(st.next().c_str(), -1);
01356             toLaneIdx = TplConvertSec<char>::_2intSec(st.next().c_str(), -1);
01357             if (fromLaneIdx >= 0 && static_cast<unsigned int>(fromLaneIdx) < from->getLanes().size() &&
01358                     toLaneIdx >= 0 && static_cast<unsigned int>(toLaneIdx) < to->getLanes().size()) {
01359                 return std::pair<MSLane*, MSLane*>(from->getLanes()[fromLaneIdx], to->getLanes()[toLaneIdx]);
01360             } else {
01361                 error += "(invalid index)";
01362             }
01363         } catch (NumberFormatException&) {
01364             error += "(number format)";
01365         }
01366     } else {
01367         error += "(malformed)";
01368     }
01369     WRITE_ERROR(error);
01370     ok = false;
01371     return std::pair<MSLane*, MSLane*>(static_cast<MSLane*>(0), static_cast<MSLane*>(0));
01372 }
01373 
01374 
01375 // ----------------------------------
01376 void
01377 NLHandler::setLocation(const SUMOSAXAttributes& attrs) {
01378     bool ok = true;
01379     PositionVector s = GeomConvHelper::parseShapeReporting(
01380                            attrs.getStringReporting(SUMO_ATTR_NET_OFFSET, 0, ok),
01381                            attrs.getObjectType(), 0, ok, false);
01382     Boundary convBoundary = GeomConvHelper::parseBoundaryReporting(
01383                                 attrs.getStringReporting(SUMO_ATTR_CONV_BOUNDARY, 0, ok),
01384                                 attrs.getObjectType(), 0, ok);
01385     Boundary origBoundary = GeomConvHelper::parseBoundaryReporting(
01386                                 attrs.getStringReporting(SUMO_ATTR_ORIG_BOUNDARY, 0, ok),
01387                                 attrs.getObjectType(), 0, ok);
01388     std::string proj = attrs.getStringReporting(SUMO_ATTR_ORIG_PROJ, 0, ok);
01389     if (ok) {
01390         Position networkOffset = s[0];
01391         GeoConvHelper::init(proj, networkOffset, origBoundary, convBoundary);
01392     }
01393 }
01394 
01395 
01396 void
01397 NLHandler::addDistrict(const SUMOSAXAttributes& attrs) {
01398     bool ok = true;
01399     myCurrentIsBroken = false;
01400     // get the id, report an error if not given or empty...
01401     myCurrentDistrictID = attrs.getStringReporting(SUMO_ATTR_ID, 0, ok);
01402     if (!ok) {
01403         myCurrentIsBroken = true;
01404         return;
01405     }
01406     try {
01407         MSEdge* sink = myEdgeControlBuilder.buildEdge(myCurrentDistrictID + "-sink");
01408         if (!MSEdge::dictionary(myCurrentDistrictID + "-sink", sink)) {
01409             delete sink;
01410             throw InvalidArgument("Another edge with the id '" + myCurrentDistrictID + "-sink' exists.");
01411         }
01412         sink->initialize(0, MSEdge::EDGEFUNCTION_DISTRICT);
01413         MSEdge* source = myEdgeControlBuilder.buildEdge(myCurrentDistrictID + "-source");
01414         if (!MSEdge::dictionary(myCurrentDistrictID + "-source", source)) {
01415             delete source;
01416             throw InvalidArgument("Another edge with the id '" + myCurrentDistrictID + "-source' exists.");
01417         }
01418         source->initialize(0, MSEdge::EDGEFUNCTION_DISTRICT);
01419         if (attrs.hasAttribute(SUMO_ATTR_EDGES)) {
01420             std::vector<std::string> desc = StringTokenizer(attrs.getString(SUMO_ATTR_EDGES)).getVector();
01421             for (std::vector<std::string>::const_iterator i = desc.begin(); i != desc.end(); ++i) {
01422                 MSEdge* edge = MSEdge::dictionary(*i);
01423                 // check whether the edge exists
01424                 if (edge == 0) {
01425                     throw InvalidArgument("The edge '" + *i + "' within district '" + myCurrentDistrictID + "' is not known.");
01426                 }
01427                 source->addFollower(edge);
01428                 edge->addFollower(sink);
01429             }
01430         }
01431     } catch (InvalidArgument& e) {
01432         WRITE_ERROR(e.what());
01433         myCurrentIsBroken = true;
01434     }
01435 }
01436 
01437 
01438 void
01439 NLHandler::addDistrictEdge(const SUMOSAXAttributes& attrs, bool isSource) {
01440     if (myCurrentIsBroken) {
01441         // earlier error
01442         return;
01443     }
01444     bool ok = true;
01445     std::string id = attrs.getStringReporting(SUMO_ATTR_ID, myCurrentDistrictID.c_str(), ok);
01446     MSEdge* succ = MSEdge::dictionary(id);
01447     if (succ != 0) {
01448         // connect edge
01449         if (isSource) {
01450             MSEdge::dictionary(myCurrentDistrictID + "-source")->addFollower(succ);
01451         } else {
01452             succ->addFollower(MSEdge::dictionary(myCurrentDistrictID + "-sink"));
01453         }
01454     } else {
01455         WRITE_ERROR("At district '" + myCurrentDistrictID + "': succeeding edge '" + id + "' does not exist.");
01456     }
01457 }
01458 
01459 
01460 // ----------------------------------
01461 
01462 
01463 void
01464 NLHandler::closeSuccLane() {
01465     // do not process internal lanes if not wished
01466     if (myCurrentIsInternalToSkip) {
01467         return;
01468     }
01469     try {
01470         mySucceedingLaneBuilder.closeSuccLane();
01471     } catch (InvalidArgument& e) {
01472         WRITE_ERROR(e.what());
01473     }
01474 }
01475 
01476 
01477 void
01478 NLHandler::endE3Detector() {
01479     try {
01480         myDetectorBuilder.endE3Detector();
01481     } catch (InvalidArgument& e) {
01482         WRITE_ERROR(e.what());
01483     }
01484 }
01485 
01486 
01487 void
01488 NLHandler::closeWAUT() {
01489     if (!myCurrentIsBroken) {
01490         try {
01491             myJunctionControlBuilder.getTLLogicControlToUse().closeWAUT(myCurrentWAUTID);
01492         } catch (InvalidArgument& e) {
01493             WRITE_ERROR(e.what());
01494             myCurrentIsBroken = true;
01495         }
01496     }
01497     myCurrentWAUTID = "";
01498 }
01499 
01500 
01501 /****************************************************************************/
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Friends Defines