SUMO - Simulation of Urban MObility

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