void NIImporter_SUMO::_loadNetwork(const OptionsCont& oc) { // check whether the option is set (properly) if (!oc.isUsableFileList("sumo-net-file")) { return; } // parse file(s) std::vector<std::string> files = oc.getStringVector("sumo-net-file"); for (std::vector<std::string>::const_iterator file = files.begin(); file != files.end(); ++file) { if (!FileHelpers::exists(*file)) { WRITE_ERROR("Could not open sumo-net-file '" + *file + "'."); return; } setFileName(*file); PROGRESS_BEGIN_MESSAGE("Parsing sumo-net from '" + *file + "'"); XMLSubSys::runParser(*this, *file); PROGRESS_DONE_MESSAGE(); } // build edges for (std::map<std::string, EdgeAttrs*>::const_iterator i = myEdges.begin(); i != myEdges.end(); ++i) { EdgeAttrs* ed = (*i).second; // skip internal edges if (ed->func == toString(EDGEFUNC_INTERNAL)) { continue; } // get and check the nodes NBNode* from = myNodeCont.retrieve(ed->fromNode); NBNode* to = myNodeCont.retrieve(ed->toNode); if (from == 0) { WRITE_ERROR("Edge's '" + ed->id + "' from-node '" + ed->fromNode + "' is not known."); continue; } if (to == 0) { WRITE_ERROR("Edge's '" + ed->id + "' to-node '" + ed->toNode + "' is not known."); continue; } // edge shape PositionVector geom; if (ed->shape.size() > 0) { geom = ed->shape; mySuspectKeepShape = false; // no problem with reconstruction if edge shape is given explicit } else { // either the edge has default shape consisting only of the two node // positions or we have a legacy network geom = reconstructEdgeShape(ed, from->getPosition(), to->getPosition()); } // build and insert the edge NBEdge* e = new NBEdge(ed->id, from, to, ed->type, ed->maxSpeed, (unsigned int) ed->lanes.size(), ed->priority, NBEdge::UNSPECIFIED_WIDTH, NBEdge::UNSPECIFIED_OFFSET, geom, ed->streetName, ed->lsf, true); // always use tryIgnoreNodePositions to keep original shape e->setLoadedLength(ed->length); if (!myNetBuilder.getEdgeCont().insert(e)) { WRITE_ERROR("Could not insert edge '" + ed->id + "'."); delete e; continue; } ed->builtEdge = myNetBuilder.getEdgeCont().retrieve(ed->id); } // assign further lane attributes (edges are built) for (std::map<std::string, EdgeAttrs*>::const_iterator i = myEdges.begin(); i != myEdges.end(); ++i) { EdgeAttrs* ed = (*i).second; NBEdge* nbe = ed->builtEdge; if (nbe == 0) { // inner edge or removed by explicit list, vclass, ... continue; } for (unsigned int fromLaneIndex = 0; fromLaneIndex < (unsigned int) ed->lanes.size(); ++fromLaneIndex) { LaneAttrs* lane = ed->lanes[fromLaneIndex]; // connections const std::vector<Connection> &connections = lane->connections; for (std::vector<Connection>::const_iterator c_it = connections.begin(); c_it != connections.end(); c_it++) { const Connection& c = *c_it; if (myEdges.count(c.toEdgeID) == 0) { WRITE_ERROR("Unknown edge '" + c.toEdgeID + "' given in connection."); continue; } NBEdge* toEdge = myEdges[c.toEdgeID]->builtEdge; if (toEdge == 0) { // removed by explicit list, vclass, ... continue; } nbe->addLane2LaneConnection( fromLaneIndex, toEdge, c.toLaneIdx, NBEdge::L2L_VALIDATED, false, c.mayDefinitelyPass); // maybe we have a tls-controlled connection if (c.tlID != "") { const std::map<std::string, NBTrafficLightDefinition*>& programs = myTLLCont.getPrograms(c.tlID); if (programs.size() > 0) { 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->addConnection(nbe, toEdge, fromLaneIndex, c.toLaneIdx, c.tlLinkNo); } else { throw ProcessError("Corrupt traffic light definition '" + c.tlID + "' (program '" + it->first + "')"); } } } else { WRITE_ERROR("The traffic light '" + c.tlID + "' is not known."); } } } // allow/disallow SUMOVehicleClasses allowed; SUMOVehicleClasses disallowed; parseVehicleClasses(lane->allow, lane->disallow, allowed, disallowed); nbe->setVehicleClasses(allowed, disallowed, fromLaneIndex); // width, offset nbe->setWidth(fromLaneIndex, lane->width); nbe->setOffset(fromLaneIndex, lane->offset); nbe->setSpeed(fromLaneIndex, lane->maxSpeed); } nbe->declareConnectionsAsLoaded(); } // insert loaded prohibitions for (std::vector<Prohibition>::const_iterator it = myProhibitions.begin(); it != myProhibitions.end(); it++) { NBEdge* prohibitedFrom = myEdges[it->prohibitedFrom]->builtEdge; if (prohibitedFrom == 0) { WRITE_ERROR("Edge '" + it->prohibitedFrom + "' in prohibition was not built"); } else { NBNode* n = prohibitedFrom->getToNode(); n->addSortedLinkFoes( NBConnection(myEdges[it->prohibitorFrom]->builtEdge, myEdges[it->prohibitorTo]->builtEdge), NBConnection(prohibitedFrom, myEdges[it->prohibitedTo]->builtEdge)); } } // final warning if (mySuspectKeepShape) { WRITE_WARNING("The input network may have been built using option 'xml.keep-shape'.\n... Accuracy of junction positions cannot be guaranteed."); } }
// =========================================================================== // method definitions // =========================================================================== // --------------------------------------------------------------------------- // static methods (interface in this case) // --------------------------------------------------------------------------- void NIImporter_OpenDrive::loadNetwork(const OptionsCont &oc, NBNetBuilder &nb) { // check whether the option is set (properly) if (!oc.isUsableFileList("opendrive")) { return; } // build the handler std::vector<OpenDriveEdge> innerEdges, outerEdges; NIImporter_OpenDrive handler(nb.getNodeCont(), innerEdges, outerEdges); // parse file(s) std::vector<std::string> files = oc.getStringVector("opendrive"); for (std::vector<std::string>::const_iterator file=files.begin(); file!=files.end(); ++file) { if (!FileHelpers::exists(*file)) { MsgHandler::getErrorInstance()->inform("Could not open opendrive file '" + *file + "'."); return; } handler.setFileName(*file); MsgHandler::getMessageInstance()->beginProcessMsg("Parsing opendrive from '" + *file + "'..."); XMLSubSys::runParser(handler, *file); MsgHandler::getMessageInstance()->endProcessMsg("done."); } // convert geometries into a discretised representation computeShapes(innerEdges); computeShapes(outerEdges); // ------------------------- // node building // ------------------------- // build nodes#1 // look at all links which belong to a node, collect their bounding boxes // and place the node in the middle of this bounding box std::map<std::string, Boundary> posMap; std::map<std::string, std::string> edge2junction; // compute node positions for (std::vector<OpenDriveEdge>::iterator i=innerEdges.begin(); i!=innerEdges.end(); ++i) { OpenDriveEdge &e = *i; assert(e.junction!="-1" && e.junction!=""); edge2junction[e.id] = e.junction; if (posMap.find(e.junction)==posMap.end()) { posMap[e.junction] = Boundary(); } posMap[e.junction].add(e.geom.getBoxBoundary()); } // build nodes for (std::map<std::string, Boundary>::iterator i=posMap.begin(); i!=posMap.end(); ++i) { if (!nb.getNodeCont().insert((*i).first, (*i).second.getCenter())) { throw ProcessError("Could not add node '" + (*i).first + "'."); } } // assign built nodes for (std::vector<OpenDriveEdge>::iterator i=outerEdges.begin(); i!=outerEdges.end(); ++i) { OpenDriveEdge &e = *i; for (std::vector<OpenDriveLink>::iterator j=e.links.begin(); j!=e.links.end(); ++j) { OpenDriveLink &l = *j; if (l.elementType!=OPENDRIVE_ET_ROAD) { // set node information setNodeSecure(nb.getNodeCont(), e, l.elementID, l.linkType); continue; } if (edge2junction.find(l.elementID)!=edge2junction.end()) { // set node information of an internal road setNodeSecure(nb.getNodeCont(), e, edge2junction[l.elementID], l.linkType); continue; } } } // we should now have all nodes set for links which are not outer edge-to-outer edge links // build nodes#2 // build nodes for all outer edge-to-outer edge connections for (std::vector<OpenDriveEdge>::iterator i=outerEdges.begin(); i!=outerEdges.end(); ++i) { OpenDriveEdge &e = *i; for (std::vector<OpenDriveLink>::iterator j=e.links.begin(); j!=e.links.end(); ++j) { OpenDriveLink &l = *j; if (l.elementType!=OPENDRIVE_ET_ROAD || edge2junction.find(l.elementID)!=edge2junction.end()) { // is a connection to an internal edge, or a node, skip continue; } // we have a direct connection between to external edges std::string id1 = e.id; std::string id2 = l.elementID; if (id1<id2) { std::swap(id1, id2); } std::string nid = id1+"."+id2; if (nb.getNodeCont().retrieve(nid)==0) { // not yet seen, build Position2D pos = l.linkType==OPENDRIVE_LT_SUCCESSOR ? e.geom[(int)e.geom.size()-1] : e.geom[0]; if (!nb.getNodeCont().insert(nid, pos)) { throw ProcessError("Could not build node '" + nid + "'."); } } /* debug-stuff else { Position2D pos = l.linkType==OPENDRIVE_LT_SUCCESSOR ? e.geom[e.geom.size()-1] : e.geom[0]; cout << nid << " " << pos << " " << nb.getNodeCont().retrieve(nid)->getPosition() << endl; } */ setNodeSecure(nb.getNodeCont(), e, nid, l.linkType); } } // we should now have start/end nodes for all outer edge-to-outer edge connections // build nodes#3 // assign further nodes generated from inner-edges // these nodes have not been assigned earlier, because the connectiosn are referenced in inner-edges for (std::vector<OpenDriveEdge>::iterator i=outerEdges.begin(); i!=outerEdges.end(); ++i) { OpenDriveEdge &e = *i; if (e.to!=0&&e.from!=0) { continue; } for (std::vector<OpenDriveEdge>::iterator j=innerEdges.begin(); j!=innerEdges.end(); ++j) { OpenDriveEdge &ie = *j; for (std::vector<OpenDriveLink>::iterator k=ie.links.begin(); k!=ie.links.end(); ++k) { OpenDriveLink &il = *k; if (il.elementType!=OPENDRIVE_ET_ROAD || il.elementID!=e.id) { // not conneted to the currently investigated outer edge continue; } std::string nid = edge2junction[ie.id]; if (il.contactPoint==OPENDRIVE_CP_START) { setNodeSecure(nb.getNodeCont(), e, nid, OPENDRIVE_LT_PREDECESSOR); } else { setNodeSecure(nb.getNodeCont(), e, nid, OPENDRIVE_LT_SUCCESSOR); } } } } // // build start/end nodes which were not defined previously for (std::vector<OpenDriveEdge>::iterator i=outerEdges.begin(); i!=outerEdges.end(); ++i) { OpenDriveEdge &e = *i; if (e.from==0) { std::string nid = e.id + ".begin"; Position2D pos(e.geometries[0].x, e.geometries[0].y); e.from = getOrBuildNode(nid, e.geom[0], nb.getNodeCont()); } if (e.to==0) { std::string nid = e.id + ".end"; Position2D pos(e.geometries[e.geometries.size()-1].x, e.geometries[e.geometries.size()-1].y); e.to = getOrBuildNode(nid, e.geom[(int)e.geom.size()-1], nb.getNodeCont()); } } // ------------------------- // edge building // ------------------------- std::map<NBEdge*, std::map<int, int> > fromLaneMap; std::map<NBEdge*, std::map<int, int> > toLaneMap; // build edges for (std::vector<OpenDriveEdge>::iterator i=outerEdges.begin(); i!=outerEdges.end(); ++i) { OpenDriveEdge &e = *i; SUMOReal speed = nb.getTypeCont().getDefaultSpeed(); int priority = nb.getTypeCont().getDefaultPriority(); unsigned int nolanes = e.getMaxLaneNumber(SUMO_TAG_OPENDRIVE_RIGHT); if (nolanes>0) { NBEdge *nbe = new NBEdge("-" + e.id, e.from, e.to, "", speed, nolanes, priority, e.geom, NBEdge::LANESPREAD_RIGHT, true); if (!nb.getEdgeCont().insert(nbe)) { throw ProcessError("Could not add edge '" + std::string("-") + e.id + "'."); } fromLaneMap[nbe] = e.laneSections.back().buildLaneMapping(SUMO_TAG_OPENDRIVE_RIGHT); toLaneMap[nbe] = e.laneSections[0].buildLaneMapping(SUMO_TAG_OPENDRIVE_RIGHT); } nolanes = e.getMaxLaneNumber(SUMO_TAG_OPENDRIVE_LEFT); if (nolanes>0) { NBEdge *nbe = new NBEdge(e.id, e.to, e.from, "", speed, nolanes, priority, e.geom.reverse(), NBEdge::LANESPREAD_RIGHT, true); if (!nb.getEdgeCont().insert(nbe)) { throw ProcessError("Could not add edge '" + e.id + "'."); } fromLaneMap[nbe] = e.laneSections[0].buildLaneMapping(SUMO_TAG_OPENDRIVE_LEFT); toLaneMap[nbe] = e.laneSections.back().buildLaneMapping(SUMO_TAG_OPENDRIVE_LEFT); } } // ------------------------- // connections building // ------------------------- std::vector<Connection> connections; // connections#1 // build connections between outer-edges for (std::vector<OpenDriveEdge>::iterator i=outerEdges.begin(); i!=outerEdges.end(); ++i) { OpenDriveEdge &e = *i; for (std::vector<OpenDriveLink>::iterator j=e.links.begin(); j!=e.links.end(); ++j) { OpenDriveLink &l = *j; if (l.elementType!=OPENDRIVE_ET_ROAD) { // we are not interested in connections to nodes continue; } if (edge2junction.find(l.elementID)!=edge2junction.end()) { // connection via an inner-road addViaConnectionSecure(nb.getEdgeCont(), nb.getNodeCont().retrieve(edge2junction[l.elementID]), e, l.linkType, l.elementID, connections); } else { // connection between two outer-edges; can be used directly std::vector<OpenDriveEdge>::iterator p = std::find_if(outerEdges.begin(), outerEdges.end(), edge_by_id_finder(l.elementID)); if (p==outerEdges.end()) { throw ProcessError("Could not find connection edge."); } std::string id1 = e.id; std::string id2 = (*p).id; if (id1<id2) { std::swap(id1, id2); } std::string nid = id1+"."+id2; if (l.linkType==OPENDRIVE_LT_PREDECESSOR) { addE2EConnectionsSecure(nb.getEdgeCont(), nb.getNodeCont().retrieve(nid), *p, e, connections); } else { addE2EConnectionsSecure(nb.getEdgeCont(), nb.getNodeCont().retrieve(nid), e, *p, connections); } } } } /* for (std::vector<OpenDriveEdge>::iterator i=innerEdges.begin(); i!=innerEdges.end(); ++i) { OpenDriveEdge &e = *i; std::string pred, succ; ContactPoint predC, succC; for (std::vector<OpenDriveLink>::iterator j=e.links.begin(); j!=e.links.end(); ++j) { OpenDriveLink &l = *j; if (l.elementType!=OPENDRIVE_ET_ROAD) { // we are not interested in connections to nodes cout << "unsupported" << endl; continue; } if(edge2junction.find(l.elementID)!=edge2junction.end()) { // not supported cout << "unsupported" << endl; continue; } if(l.linkType==OPENDRIVE_LT_SUCCESSOR) { if(succ!="") { cout << "double succ" << endl; } succ = l.elementID; succC = l.contactPoint; } else { if(pred!="") { cout << "double pred" << endl; } pred = l.elementID; predC = l.contactPoint; } } if(e.getMaxLaneNumber(SUMO_TAG_OPENDRIVE_LEFT)!=0&&e.getMaxLaneNumber(SUMO_TAG_OPENDRIVE_RIGHT)!=0) { cout << "Both dirs given!" << endl; } bool isReversed = false; if(e.getMaxLaneNumber(SUMO_TAG_OPENDRIVE_LEFT)!=0) { // std::swap(pred, succ); //std::swap(predC, succC); isReversed = true; } if(succ==""||pred=="") { cout << "Missing edge." << endl; continue; // yes, occurs } NBNode *n = nb.getNodeCont().retrieve(edge2junction[e.id]); std::vector<OpenDriveEdge>::iterator predEdge = std::find_if(outerEdges.begin(), outerEdges.end(), edge_by_id_finder(pred)); if(predEdge==outerEdges.end()) { throw ProcessError("Could not find connection edge."); } std::vector<OpenDriveEdge>::iterator succEdge = std::find_if(outerEdges.begin(), outerEdges.end(), edge_by_id_finder(succ)); if(succEdge==outerEdges.end()) { throw ProcessError("Could not find connection edge."); } NBEdge *fromEdge, *toEdge; if(!isReversed) { fromEdge = predC==OPENDRIVE_CP_END ? nb.getEdgeCont().retrieve("-" + pred) : nb.getEdgeCont().retrieve(pred); toEdge = succC==OPENDRIVE_CP_START ? nb.getEdgeCont().retrieve("-" + succ) : nb.getEdgeCont().retrieve(succ); } else { fromEdge = predC!=OPENDRIVE_CP_END ? nb.getEdgeCont().retrieve("-" + pred) : nb.getEdgeCont().retrieve(pred); toEdge = succC!=OPENDRIVE_CP_START ? nb.getEdgeCont().retrieve("-" + succ) : nb.getEdgeCont().retrieve(succ); } /* Connection c( n->hasIncoming(nb.getEdgeCont().retrieve("-" + pred)) ? nb.getEdgeCont().retrieve("-" + pred) : nb.getEdgeCont().retrieve(pred), e.id, n->hasOutgoing(nb.getEdgeCont().retrieve("-" + succ)) ? nb.getEdgeCont().retrieve("-" + succ) : nb.getEdgeCont().retrieve(succ)); / Connection c(fromEdge, e.id, toEdge); if(c.from==0||c.to==0||c.from==c.to) { throw ProcessError("Something's false"); } setLaneConnections(c, *predEdge, c.from->getID()[0]!='-', c.from->getID()[0]=='-' ? SUMO_TAG_OPENDRIVE_RIGHT : SUMO_TAG_OPENDRIVE_LEFT, e, isReversed, !isReversed ? SUMO_TAG_OPENDRIVE_RIGHT : SUMO_TAG_OPENDRIVE_LEFT, *succEdge, c.to->getID()[0]!='-', c.to->getID()[0]=='-' ? SUMO_TAG_OPENDRIVE_RIGHT : SUMO_TAG_OPENDRIVE_LEFT); connections.push_back(c); } */ for (std::vector<Connection>::const_iterator i=connections.begin(); i!=connections.end(); ++i) { if ((*i).from==0 || (*i).to==0) { std::cout << "Nope." << std::endl; continue; } (*i).from->addEdge2EdgeConnection((*i).to); std::map<int, int> fromMap = fromLaneMap[(*i).from]; std::map<int, int> toMap = fromLaneMap[(*i).to]; for (std::vector<std::pair<int, int> >::const_iterator j=(*i).lanes.begin(); j!=(*i).lanes.end(); ++j) { int fromLane = fromMap[(*j).first]; int toLane = toMap[(*j).second]; if (static_cast<unsigned int>(fromLane)>=(*i).from->getNoLanes()||fromLane<0) { std::cout << "False " << std::endl; } if (static_cast<unsigned int>(toLane)>=(*i).to->getNoLanes()||toLane<0) { std::cout << "False " << std::endl; } (*i).from->addLane2LaneConnection(fromLane, (*i).to, toLane, NBEdge::L2L_VALIDATED, true); } } }
// =========================================================================== // method definitions // =========================================================================== // --------------------------------------------------------------------------- // static methods (interface in this case) // --------------------------------------------------------------------------- void NIImporter_SUMO::loadNetwork(const OptionsCont &oc, NBNetBuilder &nb) { // check whether the option is set (properly) if (!oc.isUsableFileList("sumo-net")) { return; } // build the handler NIImporter_SUMO handler(nb.getNodeCont()); // parse file(s) std::vector<std::string> files = oc.getStringVector("sumo-net"); for (std::vector<std::string>::const_iterator file=files.begin(); file!=files.end(); ++file) { if (!FileHelpers::exists(*file)) { MsgHandler::getErrorInstance()->inform("Could not open sumo-net-file '" + *file + "'."); return; } handler.setFileName(*file); MsgHandler::getMessageInstance()->beginProcessMsg("Parsing sumo-net from '" + *file + "'..."); XMLSubSys::runParser(handler, *file); MsgHandler::getMessageInstance()->endProcessMsg("done."); } // build edges std::map<std::string, EdgeAttrs*> &loadedEdges = handler.myEdges; NBNodeCont &nodesCont = nb.getNodeCont(); NBEdgeCont &edgesCont = nb.getEdgeCont(); for (std::map<std::string, EdgeAttrs*>::const_iterator i=loadedEdges.begin(); i!=loadedEdges.end(); ++i) { EdgeAttrs *ed = (*i).second; // get and check the nodes NBNode *from = nodesCont.retrieve(ed->fromNode); NBNode *to = nodesCont.retrieve(ed->toNode); if (from==0) { MsgHandler::getErrorInstance()->inform("Edge's '" + ed->id + "' from-node '" + ed->fromNode + "' is not known."); continue; } if (to==0) { MsgHandler::getErrorInstance()->inform("Edge's '" + ed->id + "' to-node '" + ed->toNode + "' is not known."); continue; } // build and insert the edge NBEdge *e = new NBEdge(ed->id, from, to, ed->type, ed->maxSpeed, (unsigned int) ed->lanes.size(), ed->priority); if (!edgesCont.insert(e)) { MsgHandler::getErrorInstance()->inform("Could not insert edge '" + ed->id + "'."); delete e; continue; } ed->builtEdge = edgesCont.retrieve(ed->id); } // assign lane attributes (edges are built) for (std::map<std::string, EdgeAttrs*>::const_iterator i=loadedEdges.begin(); i!=loadedEdges.end(); ++i) { EdgeAttrs *ed = (*i).second; if (ed->builtEdge==0) { // earlier errors continue; } for (unsigned int j=0; j<(unsigned int) ed->lanes.size(); ++j) { const std::vector<EdgeLane> &connections = ed->lanes[j]->connections; for (std::vector<EdgeLane>::const_iterator k=connections.begin(); k!=connections.end(); ++k) { if ((*k).lane!="SUMO_NO_DESTINATION") { std::string lane = (*k).lane; std::string edge = lane.substr(0, lane.find('_')); int index = TplConvert<char>::_2int(lane.substr(lane.find('_')+1).c_str()); if (loadedEdges.find(edge)==loadedEdges.end()) { MsgHandler::getErrorInstance()->inform("Unknown edge given in succlane (for lane '" + lane + "')."); continue; } NBEdge *ce = loadedEdges.find(edge)->second->builtEdge; if (ce==0) { // earlier error or edge removal continue; } ed->builtEdge->addLane2LaneConnection(j, ce, index, NBEdge::L2L_VALIDATED); } } } } // clean up for (std::map<std::string, EdgeAttrs*>::const_iterator i=loadedEdges.begin(); i!=loadedEdges.end(); ++i) { EdgeAttrs *ed = (*i).second; for (std::vector<LaneAttrs*>::const_iterator j=ed->lanes.begin(); j!=ed->lanes.end(); ++j) { delete *j; } delete ed; } }
void NIImporter_SUMO::_loadNetwork(OptionsCont& oc) { // check whether the option is set (properly) if (!oc.isUsableFileList("sumo-net-file")) { return; } // parse file(s) std::vector<std::string> files = oc.getStringVector("sumo-net-file"); for (std::vector<std::string>::const_iterator file = files.begin(); file != files.end(); ++file) { if (!FileHelpers::isReadable(*file)) { WRITE_ERROR("Could not open sumo-net-file '" + *file + "'."); return; } setFileName(*file); PROGRESS_BEGIN_MESSAGE("Parsing sumo-net from '" + *file + "'"); XMLSubSys::runParser(*this, *file, true); PROGRESS_DONE_MESSAGE(); } // build edges for (std::map<std::string, EdgeAttrs*>::const_iterator i = myEdges.begin(); i != myEdges.end(); ++i) { EdgeAttrs* ed = (*i).second; // skip internal edges if (ed->func == EDGEFUNC_INTERNAL || ed->func == EDGEFUNC_CROSSING || ed->func == EDGEFUNC_WALKINGAREA) { continue; } // get and check the nodes NBNode* from = myNodeCont.retrieve(ed->fromNode); NBNode* to = myNodeCont.retrieve(ed->toNode); if (from == 0) { WRITE_ERROR("Edge's '" + ed->id + "' from-node '" + ed->fromNode + "' is not known."); continue; } if (to == 0) { WRITE_ERROR("Edge's '" + ed->id + "' to-node '" + ed->toNode + "' is not known."); continue; } // edge shape PositionVector geom; if (ed->shape.size() > 0) { geom = ed->shape; } else { // either the edge has default shape consisting only of the two node // positions or we have a legacy network geom = reconstructEdgeShape(ed, from->getPosition(), to->getPosition()); } // build and insert the edge NBEdge* e = new NBEdge(ed->id, from, to, ed->type, ed->maxSpeed, (unsigned int) ed->lanes.size(), ed->priority, NBEdge::UNSPECIFIED_WIDTH, NBEdge::UNSPECIFIED_OFFSET, geom, ed->streetName, "", ed->lsf, true); // always use tryIgnoreNodePositions to keep original shape e->setLoadedLength(ed->length); if (!myNetBuilder.getEdgeCont().insert(e)) { WRITE_ERROR("Could not insert edge '" + ed->id + "'."); delete e; continue; } ed->builtEdge = myNetBuilder.getEdgeCont().retrieve(ed->id); } // assign further lane attributes (edges are built) for (std::map<std::string, EdgeAttrs*>::const_iterator i = myEdges.begin(); i != myEdges.end(); ++i) { EdgeAttrs* ed = (*i).second; NBEdge* nbe = ed->builtEdge; if (nbe == 0) { // inner edge or removed by explicit list, vclass, ... continue; } for (unsigned int fromLaneIndex = 0; fromLaneIndex < (unsigned int) ed->lanes.size(); ++fromLaneIndex) { LaneAttrs* lane = ed->lanes[fromLaneIndex]; // connections const std::vector<Connection>& connections = lane->connections; for (std::vector<Connection>::const_iterator c_it = connections.begin(); c_it != connections.end(); c_it++) { const Connection& c = *c_it; if (myEdges.count(c.toEdgeID) == 0) { WRITE_ERROR("Unknown edge '" + c.toEdgeID + "' given in connection."); continue; } NBEdge* toEdge = myEdges[c.toEdgeID]->builtEdge; if (toEdge == 0) { // removed by explicit list, vclass, ... continue; } if (nbe->hasConnectionTo(toEdge, c.toLaneIdx)) { WRITE_WARNING("Target lane '" + toEdge->getLaneID(c.toLaneIdx) + "' has multiple connections from '" + nbe->getID() + "'."); } nbe->addLane2LaneConnection( fromLaneIndex, toEdge, c.toLaneIdx, NBEdge::L2L_VALIDATED, true, c.mayDefinitelyPass, c.keepClear, c.contPos); // maybe we have a tls-controlled connection if (c.tlID != "" && myRailSignals.count(c.tlID) == 0) { const std::map<std::string, NBTrafficLightDefinition*>& programs = myTLLCont.getPrograms(c.tlID); if (programs.size() > 0) { 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->addConnection(nbe, toEdge, fromLaneIndex, c.toLaneIdx, c.tlLinkNo); } else { throw ProcessError("Corrupt traffic light definition '" + c.tlID + "' (program '" + it->first + "')"); } } } else { WRITE_ERROR("The traffic light '" + c.tlID + "' is not known."); } } } // allow/disallow XXX preferred nbe->setPermissions(parseVehicleClasses(lane->allow, lane->disallow), fromLaneIndex); // width, offset nbe->setLaneWidth(fromLaneIndex, lane->width); nbe->setEndOffset(fromLaneIndex, lane->endOffset); nbe->setSpeed(fromLaneIndex, lane->maxSpeed); } nbe->declareConnectionsAsLoaded(); if (!nbe->hasLaneSpecificWidth() && nbe->getLanes()[0].width != NBEdge::UNSPECIFIED_WIDTH) { nbe->setLaneWidth(-1, nbe->getLaneWidth(0)); } if (!nbe->hasLaneSpecificEndOffset() && nbe->getEndOffset(0) != NBEdge::UNSPECIFIED_OFFSET) { nbe->setEndOffset(-1, nbe->getEndOffset(0)); } } // insert loaded prohibitions for (std::vector<Prohibition>::const_iterator it = myProhibitions.begin(); it != myProhibitions.end(); it++) { NBEdge* prohibitedFrom = myEdges[it->prohibitedFrom]->builtEdge; NBEdge* prohibitedTo = myEdges[it->prohibitedTo]->builtEdge; NBEdge* prohibitorFrom = myEdges[it->prohibitorFrom]->builtEdge; NBEdge* prohibitorTo = myEdges[it->prohibitorTo]->builtEdge; if (prohibitedFrom == 0) { WRITE_WARNING("Edge '" + it->prohibitedFrom + "' in prohibition was not built"); } else if (prohibitedTo == 0) { WRITE_WARNING("Edge '" + it->prohibitedTo + "' in prohibition was not built"); } else if (prohibitorFrom == 0) { WRITE_WARNING("Edge '" + it->prohibitorFrom + "' in prohibition was not built"); } else if (prohibitorTo == 0) { WRITE_WARNING("Edge '" + it->prohibitorTo + "' in prohibition was not built"); } else { NBNode* n = prohibitedFrom->getToNode(); n->addSortedLinkFoes( NBConnection(prohibitorFrom, prohibitorTo), NBConnection(prohibitedFrom, prohibitedTo)); } } if (!myHaveSeenInternalEdge) { myNetBuilder.haveLoadedNetworkWithoutInternalEdges(); } if (oc.isDefault("lefthand")) { oc.set("lefthand", toString(myAmLefthand)); } if (oc.isDefault("junctions.corner-detail")) { oc.set("junctions.corner-detail", toString(myCornerDetail)); } if (oc.isDefault("junctions.internal-link-detail") && myLinkDetail > 0) { oc.set("junctions.internal-link-detail", toString(myLinkDetail)); } if (!deprecatedVehicleClassesSeen.empty()) { WRITE_WARNING("Deprecated vehicle class(es) '" + toString(deprecatedVehicleClassesSeen) + "' in input network."); deprecatedVehicleClassesSeen.clear(); } // add loaded crossings if (!oc.getBool("no-internal-links")) { for (std::map<std::string, std::vector<Crossing> >::const_iterator it = myPedestrianCrossings.begin(); it != myPedestrianCrossings.end(); ++it) { NBNode* node = myNodeCont.retrieve((*it).first); for (std::vector<Crossing>::const_iterator it_c = (*it).second.begin(); it_c != (*it).second.end(); ++it_c) { const Crossing& crossing = (*it_c); EdgeVector edges; for (std::vector<std::string>::const_iterator it_e = crossing.crossingEdges.begin(); it_e != crossing.crossingEdges.end(); ++it_e) { NBEdge* edge = myNetBuilder.getEdgeCont().retrieve(*it_e); // edge might have been removed due to options if (edge != 0) { edges.push_back(edge); } } if (edges.size() > 0) { node->addCrossing(edges, crossing.width, crossing.priority, true); } } } } // add roundabouts for (std::vector<std::vector<std::string> >::const_iterator it = myRoundabouts.begin(); it != myRoundabouts.end(); ++it) { EdgeSet roundabout; for (std::vector<std::string>::const_iterator it_r = it->begin(); it_r != it->end(); ++it_r) { NBEdge* edge = myNetBuilder.getEdgeCont().retrieve(*it_r); if (edge == 0) { if (!myNetBuilder.getEdgeCont().wasIgnored(*it_r)) { WRITE_ERROR("Unknown edge '" + (*it_r) + "' in roundabout"); } } else { roundabout.insert(edge); } } myNetBuilder.getEdgeCont().addRoundabout(roundabout); } }