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