void NIImporter_SUMO::addConnection(const SUMOSAXAttributes& attrs) { bool ok = true; std::string fromID = attrs.getStringReporting(SUMO_ATTR_FROM, 0, ok); if (myEdges.count(fromID) == 0) { WRITE_ERROR("Unknown edge '" + fromID + "' given in connection."); return; } EdgeAttrs* from = myEdges[fromID]; Connection conn; conn.toEdgeID = attrs.getStringReporting(SUMO_ATTR_TO, 0, ok); unsigned int fromLaneIdx = attrs.getIntReporting(SUMO_ATTR_FROM_LANE, 0, ok); conn.toLaneIdx = attrs.getIntReporting(SUMO_ATTR_TO_LANE, 0, ok); conn.tlID = attrs.getOptStringReporting(SUMO_ATTR_TLID, 0, ok, ""); conn.mayDefinitelyPass = false; // (attrs.getStringReporting(SUMO_ATTR_STATE, 0, ok, "") == "M"); if (conn.tlID != "") { conn.tlLinkNo = attrs.getIntReporting(SUMO_ATTR_TLLINKINDEX, 0, ok); } if (from->lanes.size() <= (size_t) fromLaneIdx) { WRITE_ERROR("Invalid lane index '" + toString(fromLaneIdx) + "' for connection from '" + fromID + "'."); return; } from->lanes[fromLaneIdx]->connections.push_back(conn); }
void NIImporter_SUMO::addConnection(const SUMOSAXAttributes& attrs) { bool ok = true; std::string fromID = attrs.getStringReporting(SUMO_ATTR_FROM, 0, ok); if (myEdges.count(fromID) == 0) { WRITE_ERROR("Unknown edge '" + fromID + "' given in connection."); return; } EdgeAttrs* from = myEdges[fromID]; Connection conn; conn.toEdgeID = attrs.getStringReporting(SUMO_ATTR_TO, 0, ok); unsigned int fromLaneIdx = attrs.getIntReporting(SUMO_ATTR_FROM_LANE, 0, ok); conn.toLaneIdx = attrs.getIntReporting(SUMO_ATTR_TO_LANE, 0, ok); conn.tlID = attrs.getOptStringReporting(SUMO_ATTR_TLID, 0, ok, ""); conn.mayDefinitelyPass = attrs.getOptBoolReporting(SUMO_ATTR_PASS, 0, ok, false); const size_t suffixSize = NBRampsComputer::ADDED_ON_RAMP_EDGE.size(); if (!conn.mayDefinitelyPass && conn.toEdgeID.size() > suffixSize && conn.toEdgeID.substr(conn.toEdgeID.size() - suffixSize) == NBRampsComputer::ADDED_ON_RAMP_EDGE) { WRITE_MESSAGE("Infering connection attribute pass=\"1\" from to-edge id '" + conn.toEdgeID + "'"); conn.mayDefinitelyPass = true; } if (conn.tlID != "") { conn.tlLinkNo = attrs.getIntReporting(SUMO_ATTR_TLLINKINDEX, 0, ok); } if (from->lanes.size() <= (size_t) fromLaneIdx) { WRITE_ERROR("Invalid lane index '" + toString(fromLaneIdx) + "' for connection from '" + fromID + "'."); return; } from->lanes[fromLaneIdx]->connections.push_back(conn); }
void NIImporter_OpenStreetMap::NodesHandler::myStartElement(int element, const SUMOSAXAttributes& attrs) { ++myHierarchyLevel; if (element == SUMO_TAG_NODE) { bool ok = true; if (myHierarchyLevel != 2) { WRITE_ERROR("Node element on wrong XML hierarchy level (id='" + toString(attrs.getIntReporting(SUMO_ATTR_ID, 0, ok)) + "', level='" + toString(myHierarchyLevel) + "')."); return; } int id = attrs.getIntReporting(SUMO_ATTR_ID, 0, ok); std::string action = attrs.hasAttribute("action") ? attrs.getStringSecure("action", "") : ""; if (action == "delete") { return; } if (!ok) { return; } myLastNodeID = -1; if (myToFill.find(id) == myToFill.end()) { myLastNodeID = id; // assume we are loading multiple files... // ... so we won't report duplicate nodes bool ok = true; double tlat, tlon; std::istringstream lon(attrs.getStringReporting(SUMO_ATTR_LON, toString(id).c_str(), ok)); if (!ok) { return; } lon >> tlon; if (lon.fail()) { WRITE_ERROR("Node's '" + toString(id) + "' lon information is not numeric."); return; } std::istringstream lat(attrs.getStringReporting(SUMO_ATTR_LAT, toString(id).c_str(), ok)); if (!ok) { return; } lat >> tlat; if (lat.fail()) { WRITE_ERROR("Node's '" + toString(id) + "' lat information is not numeric."); return; } NIOSMNode* toAdd = new NIOSMNode(); toAdd->id = id; toAdd->tlsControlled = false; toAdd->lat = tlat; toAdd->lon = tlon; myIsInValidNodeTag = true; std::set<NIOSMNode*, CompareNodes>::iterator similarNode = myUniqueNodes.find(toAdd); if (similarNode == myUniqueNodes.end()) { myUniqueNodes.insert(toAdd); } else { delete toAdd; toAdd = *similarNode; WRITE_MESSAGE("Found duplicate nodes. Substituting " + toString(id) + " with " + toString(toAdd->id)); } myToFill[id] = toAdd; }
void NIXMLTrafficLightsHandler::removeTlConnection(const SUMOSAXAttributes& attrs) { bool ok = true; std::string tlID = attrs.getStringReporting(SUMO_ATTR_TLID, 0, ok); // does the traffic light still exist? const std::map<std::string, NBTrafficLightDefinition*>& programs = myTLLCont.getPrograms(tlID); if (programs.size() > 0) { // parse identifying attributes NBEdge* from = retrieveEdge(attrs, SUMO_ATTR_FROM, ok); NBEdge* to = retrieveEdge(attrs, SUMO_ATTR_TO, ok); if (!ok) { return; } int fromLane = retrieveLaneIndex(attrs, SUMO_ATTR_FROM_LANE, from, ok); int toLane = retrieveLaneIndex(attrs, SUMO_ATTR_TO_LANE, to, ok); if (!ok) { return; } int tlIndex = attrs.getIntReporting(SUMO_ATTR_TLLINKINDEX, 0, ok); NBConnection conn(from, fromLane, to, toLane, tlIndex); // remove the connection from all definitions std::map<std::string, NBTrafficLightDefinition*>::const_iterator it; for (it = programs.begin(); it != programs.end(); it++) { NBLoadedSUMOTLDef* tlDef = dynamic_cast<NBLoadedSUMOTLDef*>(it->second); if (tlDef) { tlDef->removeConnection(conn, false); } else { throw ProcessError("Corrupt traffic light definition '" + tlID + "' (program '" + it->first + "')"); } } } }
void AGActivityGenHandler::parseStation(const SUMOSAXAttributes& attrs) { if (myCurrentObject != "busLine") { return; } try { bool ok = true; int refID = attrs.getIntReporting(SUMO_ATTR_REFID, myCurrentObject.c_str(), ok); if (!ok) { throw ProcessError(); } if (!isRevStation) { currentBusLine->locateStation(myCity.statData.busStations.find(refID)->second); } else { currentBusLine->locateRevStation(myCity.statData.busStations.find(refID)->second); } } catch (const exception& e) { WRITE_ERROR("Error while parsing the element " + SUMOXMLDefinitions::Tags.getString(AGEN_TAG_STATION) + ": " + e.what()); throw ProcessError(); } }
void NIXMLEdgesHandler::addLane(const SUMOSAXAttributes& attrs) { if (myCurrentEdge == 0) { if (!OptionsCont::getOptions().isInStringVector("remove-edges.explicit", myCurrentID)) { WRITE_ERROR("Additional lane information could not be set - the edge with id '" + myCurrentID + "' is not known."); } return; } bool ok = true; int lane; if (attrs.hasAttribute(SUMO_ATTR_ID)) { lane = attrs.getIntReporting(SUMO_ATTR_ID, myCurrentID.c_str(), ok); if (!myHaveWarnedAboutDeprecatedLaneId) { myHaveWarnedAboutDeprecatedLaneId = true; WRITE_WARNING("'" + toString(SUMO_ATTR_ID) + "' is deprecated, please use '" + toString(SUMO_ATTR_INDEX) + "' instead."); } } else { lane = attrs.getIntReporting(SUMO_ATTR_INDEX, myCurrentID.c_str(), ok); } std::string allowed, disallowed, preferred; allowed = attrs.getOptStringReporting(SUMO_ATTR_ALLOW, 0, ok, ""); disallowed = attrs.getOptStringReporting(SUMO_ATTR_DISALLOW, 0, ok, ""); preferred = attrs.getOptStringReporting(SUMO_ATTR_PREFER, 0, ok, ""); if (!ok) { return; } // check whether this lane exists if (lane >= (int) myCurrentEdge->getNumLanes()) { WRITE_ERROR("Lane index is larger than number of lanes (edge '" + myCurrentID + "')."); return; } // set information about allowed / disallowed vehicle classes myCurrentEdge->setPermissions(parseVehicleClasses(allowed, disallowed), lane); myCurrentEdge->setPreferredVehicleClass(parseVehicleClasses(preferred), lane); // try to get the width if (attrs.hasAttribute(SUMO_ATTR_WIDTH)) { myCurrentEdge->setWidth(lane, attrs.getSUMORealReporting(SUMO_ATTR_WIDTH, myCurrentID.c_str(), ok)); } // try to get the end-offset (lane shortened due to pedestrian crossing etc..) if (attrs.hasAttribute(SUMO_ATTR_ENDOFFSET)) { myCurrentEdge->setOffset(lane, attrs.getSUMORealReporting(SUMO_ATTR_ENDOFFSET, myCurrentID.c_str(), ok)); } // try to get lane specific speed (should not occur for german networks) if (attrs.hasAttribute(SUMO_ATTR_SPEED)) { myCurrentEdge->setSpeed(lane, attrs.getSUMORealReporting(SUMO_ATTR_SPEED, myCurrentID.c_str(), ok)); } }
int NIXMLTrafficLightsHandler::retrieveLaneIndex( const SUMOSAXAttributes& attrs, SumoXMLAttr attr, NBEdge* edge, bool& ok) { int laneIndex = attrs.getIntReporting(attr, 0, ok); if (edge->getNumLanes() <= (size_t) laneIndex) { WRITE_ERROR("Invalid lane index '" + toString(laneIndex) + "' for edge '" + edge->getID() + "'."); ok = false; } return laneIndex; }
void NIImporter_SUMO::addSuccLane(const SUMOSAXAttributes& attrs) { if (myCurrentLane == 0) { WRITE_ERROR("Found succlane outside succ element"); return; } bool ok = true; Connection conn; std::string laneID = attrs.getStringReporting(SUMO_ATTR_LANE, 0, ok); if (laneID == "SUMO_NO_DESTINATION") { // legacy check // deprecated return; } interpretLaneID(laneID, conn.toEdgeID, conn.toLaneIdx); conn.tlID = attrs.getOptStringReporting(SUMO_ATTR_TLID, 0, ok, ""); conn.mayDefinitelyPass = false; // (attrs.getStringReporting(SUMO_ATTR_STATE, 0, ok, "") == "M"); if (conn.tlID != "") { conn.tlLinkNo = attrs.hasAttribute(SUMO_ATTR_TLLINKINDEX) ? attrs.getIntReporting(SUMO_ATTR_TLLINKINDEX, 0, ok) : attrs.getIntReporting(SUMO_ATTR_TLLINKNO__DEPRECATED, 0, ok); } myCurrentLane->connections.push_back(conn); }
void MSRouteHandler::addStop(const SUMOSAXAttributes& attrs) { bool ok = true; std::string errorSuffix; if (myActiveRouteID != "") { errorSuffix = " in route '" + myActiveRouteID + "'."; } else if (myActivePlan) { errorSuffix = " in person '" + myVehicleParameter->id + "'."; } else { errorSuffix = " in vehicle '" + myVehicleParameter->id + "'."; } SUMOVehicleParameter::Stop stop; // try to parse the assigned bus stop if (attrs.hasAttribute(SUMO_ATTR_BUS_STOP__DEPRECATED)) { stop.busstop = attrs.getStringReporting(SUMO_ATTR_BUS_STOP__DEPRECATED, 0, ok); if (!myHaveWarnedAboutDeprecatedBusStop) { myHaveWarnedAboutDeprecatedBusStop = true; WRITE_WARNING("'bus_stop' is deprecated, please use 'busStop' instead."); } } else { stop.busstop = attrs.getOptStringReporting(SUMO_ATTR_BUS_STOP, 0, ok, ""); } if (stop.busstop != "") { // ok, we have obviously a bus stop MSBusStop* bs = MSNet::getInstance()->getBusStop(stop.busstop); if (bs != 0) { const MSLane& l = bs->getLane(); stop.lane = l.getID(); stop.endPos = bs->getEndLanePosition(); stop.startPos = bs->getBeginLanePosition(); } else { WRITE_ERROR("The bus stop '" + stop.busstop + "' is not known" + errorSuffix); return; } } else { // no, the lane and the position should be given // get the lane stop.lane = attrs.getOptStringReporting(SUMO_ATTR_LANE, 0, ok, ""); if (ok && stop.lane != "") { if (MSLane::dictionary(stop.lane) == 0) { WRITE_ERROR("The lane '" + stop.lane + "' for a stop is not known" + errorSuffix); return; } } else { WRITE_ERROR("A stop must be placed on a bus stop or a lane" + errorSuffix); return; } if (myActivePlan && !myActivePlan->empty() && &myActivePlan->back()->getDestination() != &MSLane::dictionary(stop.lane)->getEdge()) { throw ProcessError("Disconnected plan for person '" + myVehicleParameter->id + "' (" + MSLane::dictionary(stop.lane)->getEdge().getID() + "!=" + myActivePlan->back()->getDestination().getID() + ")."); } stop.endPos = attrs.getOptSUMORealReporting(SUMO_ATTR_ENDPOS, 0, ok, MSLane::dictionary(stop.lane)->getLength()); if (attrs.hasAttribute(SUMO_ATTR_POSITION)) { WRITE_WARNING("Deprecated attribute 'pos' in description of stop" + errorSuffix); stop.endPos = attrs.getOptSUMORealReporting(SUMO_ATTR_POSITION, 0, ok, stop.endPos); } stop.startPos = attrs.getOptSUMORealReporting(SUMO_ATTR_STARTPOS, 0, ok, stop.endPos - 2 * POSITION_EPS); if (attrs.hasAttribute(SUMO_ATTR_FRIENDLY_POS__DEPRECATED) && !myHaveWarnedAboutDeprecatedFriendlyPos) { myHaveWarnedAboutDeprecatedFriendlyPos = true; WRITE_WARNING("'" + toString(SUMO_ATTR_FRIENDLY_POS__DEPRECATED) + "' is deprecated, use '" + toString(SUMO_ATTR_FRIENDLY_POS) + "' instead."); } bool friendlyPos = attrs.hasAttribute(SUMO_ATTR_FRIENDLY_POS__DEPRECATED) ? attrs.getOptBoolReporting(SUMO_ATTR_FRIENDLY_POS__DEPRECATED, 0, ok, false) : attrs.getOptBoolReporting(SUMO_ATTR_FRIENDLY_POS, 0, ok, false); if (!ok || !checkStopPos(stop.startPos, stop.endPos, MSLane::dictionary(stop.lane)->getLength(), POSITION_EPS, friendlyPos)) { WRITE_ERROR("Invalid start or end position for stop" + errorSuffix); return; } } // get the standing duration if (!attrs.hasAttribute(SUMO_ATTR_DURATION) && !attrs.hasAttribute(SUMO_ATTR_UNTIL)) { stop.triggered = attrs.getOptBoolReporting(SUMO_ATTR_TRIGGERED, 0, ok, true); stop.duration = -1; stop.until = -1; } else { stop.duration = attrs.getOptSUMOTimeReporting(SUMO_ATTR_DURATION, 0, ok, -1); stop.until = attrs.getOptSUMOTimeReporting(SUMO_ATTR_UNTIL, 0, ok, -1); if (!ok || (stop.duration < 0 && stop.until < 0)) { WRITE_ERROR("Invalid duration or end time is given for a stop" + errorSuffix); return; } stop.triggered = attrs.getOptBoolReporting(SUMO_ATTR_TRIGGERED, 0, ok, false); } stop.parking = attrs.getOptBoolReporting(SUMO_ATTR_PARKING, 0, ok, stop.triggered); if (!ok) { WRITE_ERROR("Invalid bool for 'triggered' or 'parking' for stop" + errorSuffix); return; } const std::string idx = attrs.getOptStringReporting(SUMO_ATTR_INDEX, 0, ok, "end"); if (idx == "end") { stop.index = STOP_INDEX_END; } else if (idx == "fit") { stop.index = STOP_INDEX_FIT; } else { stop.index = attrs.getIntReporting(SUMO_ATTR_INDEX, 0, ok); if (!ok || stop.index < 0) { WRITE_ERROR("Invalid 'index' for stop" + errorSuffix); return; } } if (myActiveRouteID != "") { myActiveRouteStops.push_back(stop); } else if (myActivePlan) { myActivePlan->push_back(new MSPerson::MSPersonStage_Waiting(MSLane::dictionary(stop.lane)->getEdge(), stop.duration, stop.until)); } else { myVehicleParameter->stops.push_back(stop); } }
void NIXMLEdgesHandler::addEdge(const SUMOSAXAttributes& attrs) { myIsUpdate = false; bool ok = true; // initialise the edge myCurrentEdge = 0; mySplits.clear(); // get the id, report an error if not given or empty... myCurrentID = attrs.getStringReporting(SUMO_ATTR_ID, 0, ok); if (!ok) { return; } myCurrentEdge = myEdgeCont.retrieve(myCurrentID); // check deprecated (unused) attributes // use default values, first myCurrentSpeed = myTypeCont.getSpeed(""); myCurrentPriority = myTypeCont.getPriority(""); myCurrentLaneNo = myTypeCont.getNumLanes(""); myPermissions = myTypeCont.getPermissions(""); myCurrentWidth = myTypeCont.getWidth(""); myCurrentOffset = NBEdge::UNSPECIFIED_OFFSET; myCurrentType = ""; myShape = PositionVector(); myLanesSpread = LANESPREAD_RIGHT; myLength = NBEdge::UNSPECIFIED_LOADED_LENGTH; myCurrentStreetName = ""; myReinitKeepEdgeShape = false; // check whether a type's values shall be used if (attrs.hasAttribute(SUMO_ATTR_TYPE)) { myCurrentType = attrs.getStringReporting(SUMO_ATTR_TYPE, myCurrentID.c_str(), ok); if (!ok) { return; } if (!myTypeCont.knows(myCurrentType)) { WRITE_ERROR("Type '" + myCurrentType + "' used by edge '" + myCurrentID + "' was not defined."); return; } myCurrentSpeed = myTypeCont.getSpeed(myCurrentType); myCurrentPriority = myTypeCont.getPriority(myCurrentType); myCurrentLaneNo = myTypeCont.getNumLanes(myCurrentType); myPermissions = myTypeCont.getPermissions(myCurrentType); myCurrentWidth = myTypeCont.getWidth(myCurrentType); } // use values from the edge to overwrite if existing, then if (myCurrentEdge != 0) { myIsUpdate = true; if (!myHaveReportedAboutOverwriting) { WRITE_MESSAGE("Duplicate edge id occured ('" + myCurrentID + "'); assuming overwriting is wished."); myHaveReportedAboutOverwriting = true; } if (attrs.getOptBoolReporting(SUMO_ATTR_REMOVE, myCurrentID.c_str(), ok, false)) { myEdgeCont.erase(myDistrictCont, myCurrentEdge); myCurrentEdge = 0; return; } myCurrentSpeed = myCurrentEdge->getSpeed(); myCurrentPriority = myCurrentEdge->getPriority(); myCurrentLaneNo = myCurrentEdge->getNumLanes(); myCurrentType = myCurrentEdge->getTypeID(); myPermissions = myCurrentEdge->getPermissions(); if (!myCurrentEdge->hasDefaultGeometry()) { myShape = myCurrentEdge->getGeometry(); myReinitKeepEdgeShape = true; } myCurrentWidth = myCurrentEdge->getWidth(); myCurrentOffset = myCurrentEdge->getOffset(); myLanesSpread = myCurrentEdge->getLaneSpreadFunction(); if (myCurrentEdge->hasLoadedLength()) { myLength = myCurrentEdge->getLoadedLength(); } myCurrentStreetName = myCurrentEdge->getStreetName(); } // speed, priority and the number of lanes have now default values; // try to read the real values from the file if (attrs.hasAttribute(SUMO_ATTR_SPEED)) { myCurrentSpeed = attrs.getSUMORealReporting(SUMO_ATTR_SPEED, myCurrentID.c_str(), ok); } if (myOptions.getBool("speed-in-kmh")) { myCurrentSpeed = myCurrentSpeed / (SUMOReal) 3.6; } // try to get the number of lanes if (attrs.hasAttribute(SUMO_ATTR_NUMLANES)) { myCurrentLaneNo = attrs.getIntReporting(SUMO_ATTR_NUMLANES, myCurrentID.c_str(), ok); } // try to get the priority if (attrs.hasAttribute(SUMO_ATTR_PRIORITY)) { myCurrentPriority = attrs.getIntReporting(SUMO_ATTR_PRIORITY, myCurrentID.c_str(), ok); } // try to get the width if (attrs.hasAttribute(SUMO_ATTR_WIDTH)) { myCurrentWidth = attrs.getSUMORealReporting(SUMO_ATTR_WIDTH, myCurrentID.c_str(), ok); } // try to get the width if (attrs.hasAttribute(SUMO_ATTR_ENDOFFSET)) { myCurrentOffset = attrs.getSUMORealReporting(SUMO_ATTR_ENDOFFSET, myCurrentID.c_str(), ok); } // try to get the street name myCurrentStreetName = attrs.getOptStringReporting(SUMO_ATTR_NAME, myCurrentID.c_str(), ok, myCurrentStreetName); // try to get the allowed/disallowed classes if (attrs.hasAttribute(SUMO_ATTR_ALLOW) || attrs.hasAttribute(SUMO_ATTR_DISALLOW)) { std::string allowS = attrs.hasAttribute(SUMO_ATTR_ALLOW) ? attrs.getStringSecure(SUMO_ATTR_ALLOW, "") : ""; std::string disallowS = attrs.hasAttribute(SUMO_ATTR_DISALLOW) ? attrs.getStringSecure(SUMO_ATTR_DISALLOW, "") : ""; // XXX matter of interpretation: should updated permissions replace or extend previously set permissions? myPermissions = parseVehicleClasses(allowS, disallowS); } // try to set the nodes if (!setNodes(attrs)) { // return if this failed return; } // try to get the shape myShape = tryGetShape(attrs); // try to get the spread type myLanesSpread = tryGetLaneSpread(attrs); // try to get the length myLength = attrs.getOptSUMORealReporting(SUMO_ATTR_LENGTH, myCurrentID.c_str(), ok, myLength); // insert the parsed edge into the edges map if (!ok) { return; } // check whether a previously defined edge shall be overwritten if (myCurrentEdge != 0) { myCurrentEdge->reinit(myFromNode, myToNode, myCurrentType, myCurrentSpeed, myCurrentLaneNo, myCurrentPriority, myShape, myCurrentWidth, myCurrentOffset, myCurrentStreetName, myLanesSpread, myReinitKeepEdgeShape); } else { // the edge must be allocated in dependence to whether a shape is given if (myShape.size() == 0) { myCurrentEdge = new NBEdge(myCurrentID, myFromNode, myToNode, myCurrentType, myCurrentSpeed, myCurrentLaneNo, myCurrentPriority, myCurrentWidth, myCurrentOffset, myCurrentStreetName, myLanesSpread); } else { myCurrentEdge = new NBEdge(myCurrentID, myFromNode, myToNode, myCurrentType, myCurrentSpeed, myCurrentLaneNo, myCurrentPriority, myCurrentWidth, myCurrentOffset, myShape, myCurrentStreetName, myLanesSpread, myKeepEdgeShape); } } myCurrentEdge->setLoadedLength(myLength); myCurrentEdge->setPermissions(myPermissions); }
void NIImporter_OpenDrive::myStartElement(SumoXMLTag element, const SUMOSAXAttributes &attrs) throw(ProcessError) { bool ok = true; switch (element) { case SUMO_TAG_OPENDRIVE_HEADER: { int majorVersion = attrs.getIntReporting(SUMO_ATTR_OPENDRIVE_REVMAJOR, "opendrive header", 0, ok); int minorVersion = attrs.getIntReporting(SUMO_ATTR_OPENDRIVE_REVMINOR, "opendrive header", 0, ok); if (majorVersion!=1||minorVersion!=2) { MsgHandler::getWarningInstance()->inform("Given openDrive file '" + getFileName() + "' uses version " + toString(majorVersion) + "." + toString(minorVersion) + ";\n Version 1.2 is supported."); } } break; case SUMO_TAG_OPENDRIVE_ROAD: { std::string id = attrs.hasAttribute(SUMO_ATTR_OPENDRIVE_ID) ? attrs.getStringReporting(SUMO_ATTR_OPENDRIVE_ID, "road", 0, ok) : attrs.getStringReporting(SUMO_ATTR_ID, "road", 0, ok); std::cout << "found edge '" << id << "'" << std::endl; std::string junction = attrs.getStringReporting(SUMO_ATTR_OPENDRIVE_JUNCTION, "road", id.c_str(), ok); SUMOReal length = attrs.getSUMORealReporting(SUMO_ATTR_OPENDRIVE_LENGTH, "road", id.c_str(), ok); myCurrentEdge = OpenDriveEdge(id, junction, length); } break; case SUMO_TAG_OPENDRIVE_PREDECESSOR: { if (myElementStack.size()>=2&&myElementStack[myElementStack.size()-2]==SUMO_TAG_OPENDRIVE_ROAD) { std::string elementType = attrs.getStringReporting(SUMO_ATTR_OPENDRIVE_ELEMENTTYPE, "predecessor", myCurrentEdge.id.c_str(), ok); std::string elementID = attrs.getStringReporting(SUMO_ATTR_OPENDRIVE_ELEMENTID, "predecessor", myCurrentEdge.id.c_str(), ok); std::string contactPoint = attrs.hasAttribute(SUMO_ATTR_OPENDRIVE_CONTACTPOINT) ? attrs.getStringReporting(SUMO_ATTR_OPENDRIVE_CONTACTPOINT, "predecessor", myCurrentEdge.id.c_str(), ok) : "end"; addLink(OPENDRIVE_LT_PREDECESSOR, elementType, elementID, contactPoint); } if (myElementStack.size()>=2&&myElementStack[myElementStack.size()-2]==SUMO_TAG_OPENDRIVE_LANE||myElementStack[myElementStack.size()-2]==SUMO_TAG_LANE) { // !!! int no = attrs.getIntReporting(SUMO_ATTR_ID, "predecessor", myCurrentEdge.id.c_str(), ok); OpenDriveLane &l = myCurrentEdge.laneSections[myCurrentEdge.laneSections.size()-1].lanesByDir[myCurrentLaneDirection].back(); l.predecessor = no; } } break; case SUMO_TAG_OPENDRIVE_SUCCESSOR: { if (myElementStack.size()>=2&&myElementStack[myElementStack.size()-2]==SUMO_TAG_OPENDRIVE_ROAD) { std::string elementType = attrs.getStringReporting(SUMO_ATTR_OPENDRIVE_ELEMENTTYPE, "successor", myCurrentEdge.id.c_str(), ok); std::string elementID = attrs.getStringReporting(SUMO_ATTR_OPENDRIVE_ELEMENTID, "successor", myCurrentEdge.id.c_str(), ok); std::string contactPoint = attrs.hasAttribute(SUMO_ATTR_OPENDRIVE_CONTACTPOINT) ? attrs.getStringReporting(SUMO_ATTR_OPENDRIVE_CONTACTPOINT, "successor", myCurrentEdge.id.c_str(), ok) : "start"; addLink(OPENDRIVE_LT_SUCCESSOR, elementType, elementID, contactPoint); } if (myElementStack.size()>=2&&myElementStack[myElementStack.size()-2]==SUMO_TAG_OPENDRIVE_LANE||myElementStack[myElementStack.size()-2]==SUMO_TAG_LANE) { // !!! int no = attrs.getIntReporting(SUMO_ATTR_ID, "predecessor", myCurrentEdge.id.c_str(), ok); OpenDriveLane &l = myCurrentEdge.laneSections[myCurrentEdge.laneSections.size()-1].lanesByDir[myCurrentLaneDirection].back(); l.successor = no; } } break; case SUMO_TAG_OPENDRIVE_GEOMETRY: { SUMOReal length = attrs.getSUMORealReporting(SUMO_ATTR_OPENDRIVE_LENGTH, "geometry", myCurrentEdge.id.c_str(), ok); SUMOReal s = attrs.getSUMORealReporting(SUMO_ATTR_OPENDRIVE_S, "geometry", myCurrentEdge.id.c_str(), ok); SUMOReal x = attrs.getSUMORealReporting(SUMO_ATTR_OPENDRIVE_X, "geometry", myCurrentEdge.id.c_str(), ok); SUMOReal y = attrs.getSUMORealReporting(SUMO_ATTR_OPENDRIVE_Y, "geometry", myCurrentEdge.id.c_str(), ok); SUMOReal hdg = attrs.getSUMORealReporting(SUMO_ATTR_OPENDRIVE_HDG, "geometry", myCurrentEdge.id.c_str(), ok); myCurrentEdge.geometries.push_back(OpenDriveGeometry(length, s, x, y, hdg)); } break; case SUMO_TAG_OPENDRIVE_LINE: { std::vector<SUMOReal> vals; addGeometryShape(OPENDRIVE_GT_LINE, vals); } break; case SUMO_TAG_OPENDRIVE_SPIRAL: { std::vector<SUMOReal> vals; vals.push_back(attrs.getSUMORealReporting(SUMO_ATTR_OPENDRIVE_CURVSTART, "spiral", myCurrentEdge.id.c_str(), ok)); vals.push_back(attrs.getSUMORealReporting(SUMO_ATTR_OPENDRIVE_CURVEND, "spiral", myCurrentEdge.id.c_str(), ok)); addGeometryShape(OPENDRIVE_GT_SPIRAL, vals); } break; case SUMO_TAG_OPENDRIVE_ARC: { std::vector<SUMOReal> vals; vals.push_back(attrs.getSUMORealReporting(SUMO_ATTR_OPENDRIVE_CURVATURE, "arc", myCurrentEdge.id.c_str(), ok)); addGeometryShape(OPENDRIVE_GT_ARC, vals); } break; case SUMO_TAG_OPENDRIVE_POLY3: { std::vector<SUMOReal> vals; vals.push_back(attrs.getSUMORealReporting(SUMO_ATTR_OPENDRIVE_A, "poly3", myCurrentEdge.id.c_str(), ok)); vals.push_back(attrs.getSUMORealReporting(SUMO_ATTR_OPENDRIVE_B, "poly3", myCurrentEdge.id.c_str(), ok)); vals.push_back(attrs.getSUMORealReporting(SUMO_ATTR_OPENDRIVE_C, "poly3", myCurrentEdge.id.c_str(), ok)); vals.push_back(attrs.getSUMORealReporting(SUMO_ATTR_OPENDRIVE_D, "poly3", myCurrentEdge.id.c_str(), ok)); addGeometryShape(OPENDRIVE_GT_POLY3, vals); } break; case SUMO_TAG_OPENDRIVE_LANESECTION: { SUMOReal s = attrs.getSUMORealReporting(SUMO_ATTR_OPENDRIVE_S, "geometry", myCurrentEdge.id.c_str(), ok); myCurrentEdge.laneSections.push_back(OpenDriveLaneSection(s)); } break; case SUMO_TAG_OPENDRIVE_LEFT: case SUMO_TAG_OPENDRIVE_CENTER: case SUMO_TAG_OPENDRIVE_RIGHT: myCurrentLaneDirection = element; break; case SUMO_TAG_LANE: // !!! case SUMO_TAG_OPENDRIVE_LANE: { std::string type = attrs.getStringReporting(SUMO_ATTR_OPENDRIVE_TYPE, "lane", myCurrentEdge.id.c_str(), ok); int id = attrs.hasAttribute(SUMO_ATTR_OPENDRIVE_ID) ? attrs.getIntReporting(SUMO_ATTR_OPENDRIVE_ID, "lane", myCurrentEdge.id.c_str(), ok) : attrs.getIntReporting(SUMO_ATTR_ID, "lane", myCurrentEdge.id.c_str(), ok); int level = attrs.hasAttribute(SUMO_ATTR_OPENDRIVE_LEVEL) ? attrs.getIntReporting(SUMO_ATTR_OPENDRIVE_LEVEL, "lane", myCurrentEdge.id.c_str(), ok) : 0; OpenDriveLaneSection &ls = myCurrentEdge.laneSections[myCurrentEdge.laneSections.size()-1]; ls.lanesByDir[myCurrentLaneDirection].push_back(OpenDriveLane(id, level, type)); } default: break; } myElementStack.push_back(element); }
void NIXMLEdgesHandler::myStartElement(SumoXMLTag element, const SUMOSAXAttributes &attrs) throw(ProcessError) { if (element==SUMO_TAG_EDGE) { myIsUpdate = false; bool ok = true; // initialise the edge myCurrentEdge = 0; mySplits.clear(); // get the id, report an error if not given or empty... if (!attrs.setIDFromAttributes("edge", myCurrentID)) { return; } myCurrentEdge = myEdgeCont.retrieve(myCurrentID); // check deprecated (unused) attributes if (!myHaveReportedAboutFunctionDeprecation&&attrs.hasAttribute(SUMO_ATTR_FUNCTION)) { MsgHandler::getWarningInstance()->inform("While parsing edge '" + myCurrentID + "': 'function' is deprecated.\n All occurences are ignored."); myHaveReportedAboutFunctionDeprecation = true; } // use default values, first myCurrentSpeed = myTypeCont.getDefaultSpeed(); myCurrentPriority = myTypeCont.getDefaultPriority(); myCurrentLaneNo = myTypeCont.getDefaultNoLanes(); // use values from the edge to overwrite if existing, then if (myCurrentEdge!=0) { myIsUpdate = true; if (!myHaveReportedAboutOverwriting) { MsgHandler::getMessageInstance()->inform("Duplicate edge id occured ('" + myCurrentID + "'); assuming overwriting is wished."); myHaveReportedAboutOverwriting = true; } myCurrentSpeed = myCurrentEdge->getSpeed(); myCurrentPriority = myCurrentEdge->getPriority(); myCurrentLaneNo = myCurrentEdge->getNoLanes(); myCurrentType = myCurrentEdge->getTypeID(); } // check whether a type's values shall be used myCurrentType = ""; if (attrs.hasAttribute(SUMO_ATTR_TYPE)) { myCurrentType = attrs.getStringReporting(SUMO_ATTR_TYPE, "edge", myCurrentID.c_str(), ok); if (!ok) { return; } if (!myTypeCont.knows(myCurrentType)) { MsgHandler::getErrorInstance()->inform("Type '" + myCurrentType + "' used by edge '" + myCurrentID + "' was not defined."); return; } myCurrentSpeed = myTypeCont.getSpeed(myCurrentType); myCurrentPriority = myTypeCont.getPriority(myCurrentType); myCurrentLaneNo = myTypeCont.getNoLanes(myCurrentType); } // speed, priority and the number of lanes have now default values; // try to read the real values from the file if (attrs.hasAttribute(SUMO_ATTR_SPEED)) { myCurrentSpeed = attrs.getSUMORealReporting(SUMO_ATTR_SPEED, "edge", myCurrentID.c_str(), ok); } if (myOptions.getBool("speed-in-kmh")) { myCurrentSpeed = myCurrentSpeed / (SUMOReal) 3.6; } // try to get the number of lanes if (attrs.hasAttribute(SUMO_ATTR_NOLANES)) { myCurrentLaneNo = attrs.getIntReporting(SUMO_ATTR_NOLANES, "edge", myCurrentID.c_str(), ok); } // try to get the priority if (attrs.hasAttribute(SUMO_ATTR_PRIORITY)) { myCurrentPriority = attrs.getIntReporting(SUMO_ATTR_PRIORITY, "edge", myCurrentID.c_str(), ok); } // try to get the shape myShape = tryGetShape(attrs); // and how to spread the lanes if (attrs.getOptStringReporting(SUMO_ATTR_SPREADFUNC, "edge", myCurrentID.c_str(), ok, "")=="center") { myLanesSpread = NBEdge::LANESPREAD_CENTER; } else { myLanesSpread = NBEdge::LANESPREAD_RIGHT; } // try to set the nodes if (!setNodes(attrs)) { // return if this failed return; } // get the length or compute it if (attrs.hasAttribute(SUMO_ATTR_LENGTH)) { myLength = attrs.getSUMORealReporting(SUMO_ATTR_LENGTH, "edge", myCurrentID.c_str(), ok); } else { myLength = 0; } /// insert the parsed edge into the edges map if (!ok) { return; } // check whether a previously defined edge shall be overwritten if (myCurrentEdge!=0) { myCurrentEdge->reinit(myFromNode, myToNode, myCurrentType, myCurrentSpeed, myCurrentLaneNo, myCurrentPriority, myShape, myLanesSpread); } else { // the edge must be allocated in dependence to whether a shape is given if (myShape.size()==0) { myCurrentEdge = new NBEdge(myCurrentID, myFromNode, myToNode, myCurrentType, myCurrentSpeed, myCurrentLaneNo, myCurrentPriority, myLanesSpread); } else { myCurrentEdge = new NBEdge(myCurrentID, myFromNode, myToNode, myCurrentType, myCurrentSpeed, myCurrentLaneNo, myCurrentPriority, myShape, myLanesSpread, OptionsCont::getOptions().getBool("xml.keep-shape")); } myCurrentEdge->setLoadedLength(myLength); } } if (element==SUMO_TAG_LANE) { if (myCurrentEdge==0) { if (!OptionsCont::getOptions().isInStringVector("remove-edges", myCurrentID)) { MsgHandler::getErrorInstance()->inform("Additional lane information could not been set - the edge with id '" + myCurrentID + "' is not known."); } return; } bool ok = true; int lane = attrs.getIntReporting(SUMO_ATTR_ID, "lane", 0, ok); std::vector<std::string> disallowed, allowed, preferred; SUMOSAXAttributes::parseStringVector(attrs.getOptStringReporting(SUMO_ATTR_DISALLOW, "lane", 0, ok, ""), disallowed); SUMOSAXAttributes::parseStringVector(attrs.getOptStringReporting(SUMO_ATTR_ALLOW, "lane", 0, ok, ""), allowed); SUMOSAXAttributes::parseStringVector(attrs.getOptStringReporting(SUMO_ATTR_PREFER, "lane", 0, ok, ""), preferred); if (!ok) { return; } if (lane<0) { MsgHandler::getErrorInstance()->inform("Missing lane-id in lane definition (edge '" + myCurrentID + "')."); return; } // check whether this lane exists if (lane>=(int) myCurrentEdge->getNoLanes()) { MsgHandler::getErrorInstance()->inform("Lane-id is larger than number of lanes (edge '" + myCurrentID + "')."); return; } // set information about allowed / disallowed vehicle classes for (std::vector<std::string>::iterator i=disallowed.begin(); i!=disallowed.end(); ++i) { myCurrentEdge->disallowVehicleClass(lane, getVehicleClassID(*i)); } for (std::vector<std::string>::iterator i=allowed.begin(); i!=allowed.end(); ++i) { myCurrentEdge->allowVehicleClass(lane, getVehicleClassID(*i)); } for (std::vector<std::string>::iterator i=preferred.begin(); i!=preferred.end(); ++i) { myCurrentEdge->preferVehicleClass(lane, getVehicleClassID(*i)); } // set information about later beginning lanes if (attrs.hasAttribute(SUMO_ATTR_FORCE_LENGTH)) { bool ok = true; int forcedLength = attrs.getIntReporting(SUMO_ATTR_FORCE_LENGTH, "lane", myCurrentID.c_str(), ok); // !!! edge id if (ok) { int nameid = forcedLength; forcedLength = (int)(myCurrentEdge->getGeometry().length() - forcedLength); std::vector<Split>::iterator i; i = find_if(mySplits.begin(), mySplits.end(), split_by_pos_finder((SUMOReal) forcedLength)); if (i==mySplits.end()) { Split e; e.pos = (SUMOReal) forcedLength; e.nameid = nameid; for (unsigned int j=0; j<myCurrentEdge->getNoLanes(); j++) { e.lanes.push_back(j); } mySplits.push_back(e); } i = find_if(mySplits.begin(), mySplits.end(), split_by_pos_finder((SUMOReal) forcedLength)); std::vector<int>::iterator k = find((*i).lanes.begin(), (*i).lanes.end(), lane); if (k!=(*i).lanes.end()) { (*i).lanes.erase(k); } } } } if (element==SUMO_TAG_SPLIT) { bool ok = true; Split e; e.pos = attrs.getSUMORealReporting(SUMO_ATTR_POSITION, "split", 0, ok); std::vector<Split>::iterator i = find_if(mySplits.begin(), mySplits.end(), split_by_pos_finder(e.pos)); if (i!=mySplits.end()) { MsgHandler::getErrorInstance()->inform("Edge '" + myCurrentID + "' has already a split at position " + toString(e.pos) + "."); return; } if (e.pos<0) { e.pos = myCurrentEdge->getGeometry().length() - e.pos; } e.nameid = (int)e.pos; if (ok) { if (myCurrentEdge==0) { if (!OptionsCont::getOptions().isInStringVector("remove-edges", myCurrentID)) { MsgHandler::getErrorInstance()->inform("Additional lane information could not been set - the edge with id '" + myCurrentID + "' is not known."); } return; } if (e.pos<0) { e.pos = myCurrentEdge->getGeometry().length() + e.pos; } std::vector<std::string> lanes; SUMOSAXAttributes::parseStringVector(attrs.getOptStringReporting(SUMO_ATTR_LANES, "split", 0, ok, ""), lanes); for (std::vector<std::string>::iterator i=lanes.begin(); i!=lanes.end(); ++i) { try { int lane = TplConvert<char>::_2int((*i).c_str()); e.lanes.push_back(lane); } catch (NumberFormatException &) { MsgHandler::getErrorInstance()->inform("Error on parsing a split (edge '" + myCurrentID + "')."); } catch (EmptyData &) { MsgHandler::getErrorInstance()->inform("Error on parsing a split (edge '" + myCurrentID + "')."); } } if (e.lanes.size()==0) { MsgHandler::getErrorInstance()->inform("Missing lane information in split of edge '" + myCurrentID + "'."); } else { mySplits.push_back(e); } } } }