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