|
SUMO - Simulation of Urban MObility
|
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 /****************************************************************************/