// =========================================================================== // method definitions // =========================================================================== // --------------------------------------------------------------------------- // static methods (interface in this case) // --------------------------------------------------------------------------- void NIImporter_ArcView::loadNetwork(const OptionsCont& oc, NBNetBuilder& nb) { if (!oc.isSet("shapefile-prefix")) { return; } // check whether the correct set of entries is given // and compute both file names std::string dbf_file = oc.getString("shapefile-prefix") + ".dbf"; std::string shp_file = oc.getString("shapefile-prefix") + ".shp"; std::string shx_file = oc.getString("shapefile-prefix") + ".shx"; // check whether the files do exist if (!FileHelpers::isReadable(dbf_file)) { WRITE_ERROR("File not accessible: " + dbf_file); } if (!FileHelpers::isReadable(shp_file)) { WRITE_ERROR("File not accessible: " + shp_file); } if (!FileHelpers::isReadable(shx_file)) { WRITE_ERROR("File not accessible: " + shx_file); } if (MsgHandler::getErrorInstance()->wasInformed()) { return; } // load the arcview files NIImporter_ArcView loader(oc, nb.getNodeCont(), nb.getEdgeCont(), nb.getTypeCont(), dbf_file, shp_file, oc.getBool("speed-in-kmh")); loader.load(); }
// =========================================================================== // method definitions // =========================================================================== // --------------------------------------------------------------------------- // static methods // --------------------------------------------------------------------------- void NIImporter_DlrNavteq::loadNetwork(const OptionsCont& oc, NBNetBuilder& nb) { // check whether the option is set (properly) if (!oc.isSet("dlr-navteq-prefix")) { return; } time_t csTime; time(&csTime); // parse file(s) LineReader lr; // load nodes std::map<std::string, PositionVector> myGeoms; PROGRESS_BEGIN_MESSAGE("Loading nodes"); std::string file = oc.getString("dlr-navteq-prefix") + "_nodes_unsplitted.txt"; NodesHandler handler1(nb.getNodeCont(), file, myGeoms); if (!lr.setFile(file)) { throw ProcessError("The file '" + file + "' could not be opened."); } lr.readAll(handler1); PROGRESS_DONE_MESSAGE(); // load street names if given and wished std::map<std::string, std::string> streetNames; // nameID : name if (oc.getBool("output.street-names")) { file = oc.getString("dlr-navteq-prefix") + "_names.txt"; if (lr.setFile(file)) { PROGRESS_BEGIN_MESSAGE("Loading Street Names"); NamesHandler handler4(file, streetNames); lr.readAll(handler4); PROGRESS_DONE_MESSAGE(); } else { WRITE_WARNING("Output will not contain street names because the file '" + file + "' was not found"); } } // load edges PROGRESS_BEGIN_MESSAGE("Loading edges"); file = oc.getString("dlr-navteq-prefix") + "_links_unsplitted.txt"; // parse the file EdgesHandler handler2(nb.getNodeCont(), nb.getEdgeCont(), nb.getTypeCont(), file, myGeoms, streetNames); if (!lr.setFile(file)) { throw ProcessError("The file '" + file + "' could not be opened."); } lr.readAll(handler2); nb.getEdgeCont().recheckLaneSpread(); PROGRESS_DONE_MESSAGE(); // load traffic lights if given file = oc.getString("dlr-navteq-prefix") + "_traffic_signals.txt"; if (lr.setFile(file)) { PROGRESS_BEGIN_MESSAGE("Loading traffic lights"); TrafficlightsHandler handler3(nb.getNodeCont(), nb.getTLLogicCont(), nb.getEdgeCont(), file); lr.readAll(handler3); PROGRESS_DONE_MESSAGE(); } // load prohibited manoeuvres if given file = oc.getString("dlr-navteq-prefix") + "_prohibited_manoeuvres.txt"; if (lr.setFile(file)) { PROGRESS_BEGIN_MESSAGE("Loading prohibited manoeuvres"); ProhibitionHandler handler6(nb.getEdgeCont(), file, csTime); lr.readAll(handler6); PROGRESS_DONE_MESSAGE(); } // load connected lanes if given file = oc.getString("dlr-navteq-prefix") + "_connected_lanes.txt"; if (lr.setFile(file)) { PROGRESS_BEGIN_MESSAGE("Loading connected lanes"); ConnectedLanesHandler handler7(nb.getEdgeCont()); lr.readAll(handler7); PROGRESS_DONE_MESSAGE(); } // load time restrictions if given file = oc.getString("dlr-navteq-prefix") + "_links_timerestrictions.txt"; if (lr.setFile(file)) { PROGRESS_BEGIN_MESSAGE("Loading time restrictions"); if (!oc.isDefault("construction-date")) { csTime = readDate(oc.getString("construction-date")); } TimeRestrictionsHandler handler5(nb.getEdgeCont(), nb.getDistrictCont(), csTime); lr.readAll(handler5); handler5.printSummary(); PROGRESS_DONE_MESSAGE(); } }
void NIImporter_OpenStreetMap::_loadNetwork(const OptionsCont& oc, NBNetBuilder& nb) { // check whether the option is set (properly) if (!oc.isSet("osm-files")) { return; } // preset types // for highways NBTypeCont& tc = nb.getTypeCont(); SUMOReal const WIDTH = NBEdge::UNSPECIFIED_WIDTH; tc.insert("highway.motorway", 3, (SUMOReal)(160./ 3.6), 13, WIDTH, SVC_UNKNOWN, true); tc.insert("highway.motorway_link", 1, (SUMOReal)(80. / 3.6), 12, WIDTH, SVC_UNKNOWN, true); tc.insert("highway.trunk", 2, (SUMOReal)(100./ 3.6), 11, WIDTH); // !!! 130km/h? tc.insert("highway.trunk_link", 1, (SUMOReal)(80. / 3.6), 10, WIDTH); tc.insert("highway.primary", 2, (SUMOReal)(100./ 3.6), 9, WIDTH); tc.insert("highway.primary_link", 1, (SUMOReal)(80. / 3.6), 8, WIDTH); tc.insert("highway.secondary", 2, (SUMOReal)(100./ 3.6), 7, WIDTH); tc.insert("highway.secondary_link",1, (SUMOReal)(80. / 3.6), 6, WIDTH); tc.insert("highway.tertiary", 1, (SUMOReal)(80. / 3.6), 6, WIDTH); tc.insert("highway.tertiary_link", 1, (SUMOReal)(80. / 3.6), 5, WIDTH); tc.insert("highway.unclassified", 1, (SUMOReal)(80. / 3.6), 5, WIDTH); tc.insert("highway.residential", 1, (SUMOReal)(50. / 3.6), 4, WIDTH); // actually, maybe one lane for parking would be nice... tc.insert("highway.living_street", 1, (SUMOReal)(10. / 3.6), 3, WIDTH); tc.insert("highway.service", 1, (SUMOReal)(20. / 3.6), 2, WIDTH, SVC_DELIVERY); tc.insert("highway.track", 1, (SUMOReal)(20. / 3.6), 1, WIDTH); tc.insert("highway.services", 1, (SUMOReal)(30. / 3.6), 1, WIDTH); tc.insert("highway.unsurfaced", 1, (SUMOReal)(30. / 3.6), 1, WIDTH); // unofficial value, used outside germany tc.insert("highway.footway", 1, (SUMOReal)(30. / 3.6), 1, WIDTH, SVC_PEDESTRIAN); tc.insert("highway.pedestrian", 1, (SUMOReal)(30. / 3.6), 1, WIDTH, SVC_PEDESTRIAN); tc.insert("highway.path", 1, (SUMOReal)(10. / 3.6), 1, WIDTH, SVC_PEDESTRIAN); tc.insert("highway.bridleway", 1, (SUMOReal)(10. / 3.6), 1, WIDTH, SVC_BICYCLE); // no horse stuff tc.insert("highway.cycleway", 1, (SUMOReal)(20. / 3.6), 1, WIDTH, SVC_BICYCLE); tc.insert("highway.footway", 1, (SUMOReal)(10. / 3.6), 1, WIDTH, SVC_PEDESTRIAN); tc.insert("highway.step", 1, (SUMOReal)(5. / 3.6), 1, WIDTH, SVC_PEDESTRIAN); // additional tc.insert("highway.steps", 1, (SUMOReal)(5. / 3.6), 1, WIDTH, SVC_PEDESTRIAN); // :-) do not run too fast tc.insert("highway.stairs", 1, (SUMOReal)(5. / 3.6), 1, WIDTH, SVC_PEDESTRIAN); // additional tc.insert("highway.bus_guideway", 1, (SUMOReal)(30. / 3.6), 1, WIDTH, SVC_BUS); tc.insert("highway.raceway", 2, (SUMOReal)(300./ 3.6), 14, WIDTH, SVC_VIP); tc.insert("highway.ford", 1, (SUMOReal)(10. / 3.6), 1, WIDTH, SVC_PUBLIC_ARMY); // for railways tc.insert("railway.rail", 1, (SUMOReal)(30. / 3.6), 1, WIDTH, SVC_RAIL_FAST); tc.insert("railway.tram", 1, (SUMOReal)(30. / 3.6), 1, WIDTH, SVC_CITYRAIL); tc.insert("railway.light_rail", 1, (SUMOReal)(30. / 3.6), 1, WIDTH, SVC_LIGHTRAIL); tc.insert("railway.subway", 1, (SUMOReal)(30. / 3.6), 1, WIDTH, SVC_CITYRAIL); tc.insert("railway.preserved", 1, (SUMOReal)(30. / 3.6), 1, WIDTH, SVC_LIGHTRAIL); tc.insert("railway.monorail", 1, (SUMOReal)(30. / 3.6), 1, WIDTH, SVC_LIGHTRAIL); // rail stuff has to be discussed /* Parse file(s) * Each file is parsed twice: first for nodes, second for edges. */ std::vector<std::string> files = oc.getStringVector("osm-files"); // load nodes, first NodesHandler nodesHandler(myOSMNodes, myUniqueNodes); for (std::vector<std::string>::const_iterator file = files.begin(); file != files.end(); ++file) { // nodes if (!FileHelpers::exists(*file)) { WRITE_ERROR("Could not open osm-file '" + *file + "'."); return; } nodesHandler.setFileName(*file); PROGRESS_BEGIN_MESSAGE("Parsing nodes from osm-file '" + *file + "'"); if (!XMLSubSys::runParser(nodesHandler, *file)) { return; } PROGRESS_DONE_MESSAGE(); } // load edges, then EdgesHandler edgesHandler(myOSMNodes, myEdges); for (std::vector<std::string>::const_iterator file = files.begin(); file != files.end(); ++file) { // edges edgesHandler.setFileName(*file); PROGRESS_BEGIN_MESSAGE("Parsing edges from osm-file '" + *file + "'"); XMLSubSys::runParser(edgesHandler, *file); PROGRESS_DONE_MESSAGE(); } /* Remove duplicate edges with the same shape and attributes */ if (!OptionsCont::getOptions().getBool("osm.skip-duplicates-check")) { PROGRESS_BEGIN_MESSAGE("Removing duplicate edges"); if (myEdges.size() > 1) { std::set<const Edge*, CompareEdges> dupsFinder; for (std::map<std::string, Edge*>::iterator it = myEdges.begin(); it != myEdges.end();) { if (dupsFinder.count(it->second) > 0) { WRITE_MESSAGE("Found duplicate edges. Removing " + it->first); delete it->second; myEdges.erase(it++); } else { dupsFinder.insert(it->second); it++; } } } PROGRESS_DONE_MESSAGE(); } /* Mark which nodes are used (by edges or traffic lights). * This is necessary to detect which OpenStreetMap nodes are for * geometry only */ std::map<int, int> nodeUsage; // Mark which nodes are used by edges (begin and end) for (std::map<std::string, Edge*>::const_iterator i = myEdges.begin(); i != myEdges.end(); ++i) { Edge* e = (*i).second; assert(e->myCurrentIsRoad); for (std::vector<int>::const_iterator j = e->myCurrentNodes.begin(); j != e->myCurrentNodes.end(); ++j) { if (nodeUsage.find(*j) == nodeUsage.end()) { nodeUsage[*j] = 0; } nodeUsage[*j] = nodeUsage[*j] + 1; } } // Mark which nodes are used by traffic lights for (std::map<int, NIOSMNode*>::const_iterator nodesIt = myOSMNodes.begin(); nodesIt != myOSMNodes.end(); ++nodesIt) { if (nodesIt->second->tlsControlled) { // If the key is not found in the map, the value is automatically // initialized with 0. nodeUsage[nodesIt->first] += 1; } } /* Instantiate edges * Only those nodes in the middle of an edge which are used by more than * one edge are instantiated. Other nodes are considered as geometry nodes. */ NBNodeCont& nc = nb.getNodeCont(); NBEdgeCont& ec = nb.getEdgeCont(); NBTrafficLightLogicCont& tlsc = nb.getTLLogicCont(); for (std::map<std::string, Edge*>::iterator i = myEdges.begin(); i != myEdges.end(); ++i) { Edge* e = (*i).second; assert(e->myCurrentIsRoad); // build nodes; // the from- and to-nodes must be built in any case // the geometry nodes are only built if more than one edge references them NBNode* currentFrom = insertNodeChecking(*e->myCurrentNodes.begin(), nc, tlsc); NBNode* last = insertNodeChecking(*(e->myCurrentNodes.end() - 1), nc, tlsc); int running = 0; std::vector<int> passed; for (std::vector<int>::iterator j = e->myCurrentNodes.begin(); j != e->myCurrentNodes.end(); ++j) { passed.push_back(*j); if (nodeUsage[*j] > 1 && j != e->myCurrentNodes.end() - 1 && j != e->myCurrentNodes.begin()) { NBNode* currentTo = insertNodeChecking(*j, nc, tlsc); insertEdge(e, running, currentFrom, currentTo, passed, ec, tc); currentFrom = currentTo; running++; passed.clear(); } } if (running == 0) { running = -1; } insertEdge(e, running, currentFrom, last, passed, ec, tc); } }
// =========================================================================== // 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 // --------------------------------------------------------------------------- void NWWriter_SUMO::writeNetwork(const OptionsCont& oc, NBNetBuilder& nb) { // check whether a sumo net-file shall be generated if (!oc.isSet("output-file")) { return; } OutputDevice& device = OutputDevice::getDevice(oc.getString("output-file")); const std::string lefthand = oc.getBool("lefthand") ? " " + toString(SUMO_ATTR_LEFTHAND) + "=\"true\"" : ""; const int cornerDetail = oc.getInt("junctions.corner-detail"); const int linkDetail = oc.getInt("junctions.internal-link-detail"); const std::string junctionCornerDetail = (cornerDetail > 0 ? " " + toString(SUMO_ATTR_CORNERDETAIL) + "=\"" + toString(cornerDetail) + "\"" : ""); const std::string junctionLinkDetail = (oc.isDefault("junctions.internal-link-detail") ? "" : " " + toString(SUMO_ATTR_LINKDETAIL) + "=\"" + toString(linkDetail) + "\""); device.writeXMLHeader("net", NWFrame::MAJOR_VERSION + lefthand + junctionCornerDetail + junctionLinkDetail + " xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:noNamespaceSchemaLocation=\"http://sumo.dlr.de/xsd/net_file.xsd\""); // street names may contain non-ascii chars device.lf(); // get involved container const NBNodeCont& nc = nb.getNodeCont(); const NBEdgeCont& ec = nb.getEdgeCont(); const NBDistrictCont& dc = nb.getDistrictCont(); // write network offsets and projection GeoConvHelper::writeLocation(device); // write edge types and restrictions nb.getTypeCont().writeTypes(device); // write inner lanes bool origNames = oc.getBool("output.original-names"); if (!oc.getBool("no-internal-links")) { bool hadAny = false; for (std::map<std::string, NBNode*>::const_iterator i = nc.begin(); i != nc.end(); ++i) { hadAny |= writeInternalEdges(device, *(*i).second, origNames); } if (hadAny) { device.lf(); } } // write edges with lanes and connected edges bool noNames = !oc.getBool("output.street-names"); for (std::map<std::string, NBEdge*>::const_iterator i = ec.begin(); i != ec.end(); ++i) { writeEdge(device, *(*i).second, noNames, origNames); } device.lf(); // write tls logics writeTrafficLights(device, nb.getTLLogicCont()); // write the nodes (junctions) std::set<NBNode*> roundaboutNodes; const bool checkLaneFoesAll = oc.getBool("check-lane-foes.all"); const bool checkLaneFoesRoundabout = !checkLaneFoesAll && oc.getBool("check-lane-foes.roundabout"); if (checkLaneFoesRoundabout) { const std::set<EdgeSet>& roundabouts = ec.getRoundabouts(); for (std::set<EdgeSet>::const_iterator i = roundabouts.begin(); i != roundabouts.end(); ++i) { for (EdgeSet::const_iterator j = (*i).begin(); j != (*i).end(); ++j) { roundaboutNodes.insert((*j)->getToNode()); } } } for (std::map<std::string, NBNode*>::const_iterator i = nc.begin(); i != nc.end(); ++i) { const bool checkLaneFoes = checkLaneFoesAll || (checkLaneFoesRoundabout && roundaboutNodes.count((*i).second) > 0); writeJunction(device, *(*i).second, checkLaneFoes); } device.lf(); const bool includeInternal = !oc.getBool("no-internal-links"); if (includeInternal) { // ... internal nodes if not unwanted bool hadAny = false; for (std::map<std::string, NBNode*>::const_iterator i = nc.begin(); i != nc.end(); ++i) { hadAny |= writeInternalNodes(device, *(*i).second); } if (hadAny) { device.lf(); } } // write the successors of lanes unsigned int numConnections = 0; for (std::map<std::string, NBEdge*>::const_iterator it_edge = ec.begin(); it_edge != ec.end(); it_edge++) { NBEdge* from = it_edge->second; from->sortOutgoingConnectionsByIndex(); const std::vector<NBEdge::Connection> connections = from->getConnections(); numConnections += (unsigned int)connections.size(); for (std::vector<NBEdge::Connection>::const_iterator it_c = connections.begin(); it_c != connections.end(); it_c++) { writeConnection(device, *from, *it_c, includeInternal); } } if (numConnections > 0) { device.lf(); } if (includeInternal) { // ... internal successors if not unwanted bool hadAny = false; for (std::map<std::string, NBNode*>::const_iterator i = nc.begin(); i != nc.end(); ++i) { hadAny |= writeInternalConnections(device, *(*i).second); } if (hadAny) { device.lf(); } } for (std::map<std::string, NBNode*>::const_iterator i = nc.begin(); i != nc.end(); ++i) { NBNode* node = (*i).second; // write connections from pedestrian crossings const std::vector<NBNode::Crossing>& crossings = node->getCrossings(); for (std::vector<NBNode::Crossing>::const_iterator it = crossings.begin(); it != crossings.end(); it++) { NWWriter_SUMO::writeInternalConnection(device, (*it).id, (*it).nextWalkingArea, 0, 0, ""); } // write connections from pedestrian walking areas const std::vector<NBNode::WalkingArea>& WalkingAreas = node->getWalkingAreas(); for (std::vector<NBNode::WalkingArea>::const_iterator it = WalkingAreas.begin(); it != WalkingAreas.end(); it++) { if ((*it).nextCrossing != "") { const NBNode::Crossing& nextCrossing = node->getCrossing((*it).nextCrossing); // connection to next crossing (may be tls-controlled) device.openTag(SUMO_TAG_CONNECTION); device.writeAttr(SUMO_ATTR_FROM, (*it).id); device.writeAttr(SUMO_ATTR_TO, (*it).nextCrossing); device.writeAttr(SUMO_ATTR_FROM_LANE, 0); device.writeAttr(SUMO_ATTR_TO_LANE, 0); if (node->isTLControlled()) { device.writeAttr(SUMO_ATTR_TLID, (*node->getControllingTLS().begin())->getID()); assert(nextCrossing.tlLinkNo >= 0); device.writeAttr(SUMO_ATTR_TLLINKINDEX, nextCrossing.tlLinkNo); } device.writeAttr(SUMO_ATTR_DIR, LINKDIR_STRAIGHT); device.writeAttr(SUMO_ATTR_STATE, nextCrossing.priority ? LINKSTATE_MAJOR : LINKSTATE_MINOR); device.closeTag(); } // optional connections from/to sidewalk for (std::vector<std::string>::const_iterator it_sw = (*it).nextSidewalks.begin(); it_sw != (*it).nextSidewalks.end(); ++it_sw) { NWWriter_SUMO::writeInternalConnection(device, (*it).id, (*it_sw), 0, 0, ""); } for (std::vector<std::string>::const_iterator it_sw = (*it).prevSidewalks.begin(); it_sw != (*it).prevSidewalks.end(); ++it_sw) { NWWriter_SUMO::writeInternalConnection(device, (*it_sw), (*it).id, 0, 0, ""); } } } // write loaded prohibitions for (std::map<std::string, NBNode*>::const_iterator i = nc.begin(); i != nc.end(); ++i) { writeProhibitions(device, i->second->getProhibitions()); } // write roundabout information writeRoundabouts(device, ec.getRoundabouts(), ec); // write the districts for (std::map<std::string, NBDistrict*>::const_iterator i = dc.begin(); i != dc.end(); i++) { writeDistrict(device, *(*i).second); } if (dc.size() != 0) { device.lf(); } device.close(); }