// ===========================================================================
// 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 (interface in this case)
// ---------------------------------------------------------------------------
void
NIImporter_RobocupRescue::loadNetwork(const OptionsCont& oc, NBNetBuilder& nb) {
    // check whether the option is set (properly)
    if (!oc.isSet("robocup-dir")) {
        return;
    }
    // build the handler
    NIImporter_RobocupRescue handler(nb.getNodeCont(), nb.getEdgeCont());
    // parse file(s)
    std::vector<std::string> files = oc.getStringVector("robocup-dir");
    for (std::vector<std::string>::const_iterator file = files.begin(); file != files.end(); ++file) {
        // nodes
        std::string nodesName = (*file) + "/node.bin";
        if (!FileHelpers::exists(nodesName)) {
            WRITE_ERROR("Could not open robocup-node-file '" + nodesName + "'.");
            return;
        }
        PROGRESS_BEGIN_MESSAGE("Parsing robocup-nodes from '" + nodesName + "'");
        handler.loadNodes(nodesName);
        PROGRESS_DONE_MESSAGE();
        // edges
        std::string edgesName = (*file) + "/road.bin";
        if (!FileHelpers::exists(edgesName)) {
            WRITE_ERROR("Could not open robocup-road-file '" + edgesName + "'.");
            return;
        }
        PROGRESS_BEGIN_MESSAGE("Parsing robocup-roads from '" + edgesName + "'");
        handler.loadEdges(edgesName);
        PROGRESS_DONE_MESSAGE();
    }
}
// ===========================================================================
// method definitions
// ===========================================================================
// ---------------------------------------------------------------------------
// static methods
// ---------------------------------------------------------------------------
void
NIImporter_MATSim::loadNetwork(const OptionsCont& oc, NBNetBuilder& nb) {
    // check whether the option is set (properly)
    if (!oc.isSet("matsim-files")) {
        return;
    }
    /* Parse file(s)
     * Each file is parsed twice: first for nodes, second for edges. */
    std::vector<std::string> files = oc.getStringVector("matsim-files");
    // load nodes, first
    NodesHandler nodesHandler(nb.getNodeCont());
    for (std::vector<std::string>::const_iterator file = files.begin(); file != files.end(); ++file) {
        // nodes
        if (!FileHelpers::isReadable(*file)) {
            WRITE_ERROR("Could not open matsim-file '" + *file + "'.");
            return;
        }
        nodesHandler.setFileName(*file);
        PROGRESS_BEGIN_MESSAGE("Parsing nodes from matsim-file '" + *file + "'");
        if (!XMLSubSys::runParser(nodesHandler, *file)) {
            return;
        }
        PROGRESS_DONE_MESSAGE();
    }
    // load edges, then
    EdgesHandler edgesHandler(nb.getNodeCont(), nb.getEdgeCont(), oc.getBool("matsim.keep-length"),
                              oc.getBool("matsim.lanes-from-capacity"), NBCapacity2Lanes(oc.getFloat("lanes-from-capacity.norm")));
    for (std::vector<std::string>::const_iterator file = files.begin(); file != files.end(); ++file) {
        // edges
        edgesHandler.setFileName(*file);
        PROGRESS_BEGIN_MESSAGE("Parsing edges from matsim-file '" + *file + "'");
        XMLSubSys::runParser(edgesHandler, *file);
        PROGRESS_DONE_MESSAGE();
    }
}
/* -------------------------------------------------------------------------
 * main
 * ----------------------------------------------------------------------- */
int
main(int argc, char** argv) {
    OptionsCont& oc = OptionsCont::getOptions();
    // give some application descriptions
    oc.setApplicationDescription("Road network importer / builder for the road traffic simulation SUMO.");
    oc.setApplicationName("netconvert", "SUMO netconvert Version " + (std::string)VERSION_STRING);
    int ret = 0;
    try {
        XMLSubSys::init(false);
        fillOptions();
        OptionsIO::getOptions(true, argc, argv);
        if (oc.processMetaOptions(argc < 2)) {
            SystemFrame::close();
            return 0;
        }
        MsgHandler::initOutputOptions();
        if (!checkOptions()) {
            throw ProcessError();
        }
        RandHelper::initRandGlobal();
        NBNetBuilder nb;
        nb.applyOptions(oc);
        // load data
        NILoader nl(nb);
        nl.load(oc);
        if (oc.getBool("ignore-errors")) {
            MsgHandler::getErrorInstance()->clear();
        }
        // check whether any errors occured
        if (MsgHandler::getErrorInstance()->wasInformed()) {
            throw ProcessError();
        }
        nb.compute(oc);
        if(oc.getAnyVerbosity())
          std::cout<<"Writing output file..."<<std::endl;
        NWFrame::writeNetwork(oc, nb);
        if(oc.getAnyVerbosity())
          std::cout<<"Output file writed"<<std::endl;
    } catch (ProcessError& e) {
        if (std::string(e.what()) != std::string("Process Error") && std::string(e.what()) != std::string("")) {
            WRITE_ERROR(e.what());
        }
        MsgHandler::getErrorInstance()->inform("Quitting (on error).", false);
        ret = 1;
#ifndef _DEBUG
    } catch (...) {
        MsgHandler::getErrorInstance()->inform("Quitting (on unknown error).", false);
        ret = 1;
#endif
    }
    NBDistribution::clear();
    OutputDevice::closeAll();
    SystemFrame::close();
    // report about ending
    if (ret == 0) {
        std::cout << "Success." << std::endl;
    }
    return ret;
}
// ---------------------------------------------------------------------------
// static methods
// ---------------------------------------------------------------------------
void
NWWriter_DlrNavteq::writeNetwork(const OptionsCont& oc, NBNetBuilder& nb) {
    // check whether a matsim-file shall be generated
    if (!oc.isSet("dlr-navteq-output")) {
        return;
    }
    writeNodesUnsplitted(oc, nb.getNodeCont(), nb.getEdgeCont());
    writeLinksUnsplitted(oc, nb.getEdgeCont());
}
// ---------------------------------------------------------------------------
// loader methods
// ---------------------------------------------------------------------------
NIImporter_SUMO::NIImporter_SUMO(NBNetBuilder& nb)
    : SUMOSAXHandler("sumo-network"),
      myNetBuilder(nb),
      myNodeCont(nb.getNodeCont()),
      myTLLCont(nb.getTLLogicCont()),
      myCurrentEdge(0),
      myCurrentLane(0),
      myCurrentTL(0),
      myLocation(0),
      mySuspectKeepShape(false) {}
Exemple #7
0
int
main(int argc, char** argv) {
    OptionsCont& oc = OptionsCont::getOptions();
    // give some application descriptions
    oc.setApplicationDescription("Road network generator for the microscopic road traffic simulation SUMO.");
    oc.setApplicationName("netgen", "SUMO netgen Version " + (std::string)VERSION_STRING);
    int ret = 0;
    try {
        // initialise the application system (messaging, xml, options)
        XMLSubSys::init(false);
        fillOptions();
        OptionsIO::getOptions(true, argc, argv);
        if (oc.processMetaOptions(argc < 2)) {
            SystemFrame::close();
            return 0;
        }
        MsgHandler::initOutputOptions();
        if (!checkOptions()) {
            throw ProcessError();
        }
        RandHelper::initRandGlobal();
        NBNetBuilder nb;
        nb.applyOptions(oc);
        // build the netgen-network description
        NGNet* net = buildNetwork(nb);
        // ... and we have to do this...
        oc.resetWritable();
        // transfer to the netbuilding structures
        net->toNB();
        delete net;
        // report generated structures
        WRITE_MESSAGE(" Generation done;");
        WRITE_MESSAGE("   " + toString<int>(nb.getNodeCont().size()) + " nodes generated.");
        WRITE_MESSAGE("   " + toString<int>(nb.getEdgeCont().size()) + " edges generated.");
        nb.compute(oc);
        NWFrame::writeNetwork(oc, nb);
    } catch (ProcessError& e) {
        if (std::string(e.what()) != std::string("Process Error") && std::string(e.what()) != std::string("")) {
            WRITE_ERROR(e.what());
        }
        MsgHandler::getErrorInstance()->inform("Quitting (on error).", false);
        ret = 1;
#ifndef _DEBUG
    } catch (...) {
        MsgHandler::getErrorInstance()->inform("Quitting (on unknown error).", false);
        ret = 1;
#endif
    }
    OutputDevice::closeAll();
    SystemFrame::close();
    if (ret == 0) {
        std::cout << "Success." << std::endl;
    }
    return ret;
}
// ---------------------------------------------------------------------------
// loader methods
// ---------------------------------------------------------------------------
NIImporter_SUMO::NIImporter_SUMO(NBNetBuilder& nb)
    : SUMOSAXHandler("sumo-network"),
      myNetBuilder(nb),
      myNodeCont(nb.getNodeCont()),
      myTLLCont(nb.getTLLogicCont()),
      myCurrentEdge(0),
      myCurrentLane(0),
      myCurrentTL(0),
      myLocation(0),
      mySuspectKeepShape(false),
      myHaveWarnedAboutDeprecatedSpreadType(false),
      myHaveWarnedAboutDeprecatedMaxSpeed(false) {}
// ---------------------------------------------------------------------------
// loader methods
// ---------------------------------------------------------------------------
NIImporter_SUMO::NIImporter_SUMO(NBNetBuilder& nb)
    : SUMOSAXHandler("sumo-network"),
      myNetBuilder(nb),
      myNodeCont(nb.getNodeCont()),
      myTLLCont(nb.getTLLogicCont()),
      myCurrentEdge(0),
      myCurrentLane(0),
      myCurrentTL(0),
      myLocation(0),
      myHaveSeenInternalEdge(false),
      myAmLefthand(false),
      myCornerDetail(0),
      myLinkDetail(-1) {
}
// ===========================================================================
// method definitions
// ===========================================================================
// ---------------------------------------------------------------------------
// NBRampsComputer
// ---------------------------------------------------------------------------
void
NBRampsComputer::computeRamps(NBNetBuilder& nb, OptionsCont& oc) {
    SUMOReal minHighwaySpeed = oc.getFloat("ramps.min-highway-speed");
    SUMOReal maxRampSpeed = oc.getFloat("ramps.max-ramp-speed");
    SUMOReal rampLength = oc.getFloat("ramps.ramp-length");
    bool dontSplit = oc.getBool("ramps.no-split");
    std::set<NBEdge*> incremented;
    // check whether on-off ramps shall be guessed
    if (oc.getBool("ramps.guess")) {
        NBNodeCont& nc = nb.getNodeCont();
        NBEdgeCont& ec = nb.getEdgeCont();
        NBDistrictCont& dc = nb.getDistrictCont();
        std::set<NBNode*> potOnRamps;
        std::set<NBNode*> potOffRamps;
        for (std::map<std::string, NBNode*>::const_iterator i = nc.begin(); i != nc.end(); ++i) {
            NBNode* cur = (*i).second;
            if (mayNeedOnRamp(cur, minHighwaySpeed, maxRampSpeed)) {
                potOnRamps.insert(cur);
            }
            if (mayNeedOffRamp(cur, minHighwaySpeed, maxRampSpeed)) {
                potOffRamps.insert(cur);
            }
        }
        for (std::set<NBNode*>::const_iterator i = potOnRamps.begin(); i != potOnRamps.end(); ++i) {
            buildOnRamp(*i, nc, ec, dc, rampLength, dontSplit, incremented);
        }
        for (std::set<NBNode*>::const_iterator i = potOffRamps.begin(); i != potOffRamps.end(); ++i) {
            buildOffRamp(*i, nc, ec, dc, rampLength, dontSplit, incremented);
        }
    }
    // check whether on-off ramps shall be guessed
    if (oc.isSet("ramps.set")) {
        std::vector<std::string> edges = oc.getStringVector("ramps.set");
        NBNodeCont& nc = nb.getNodeCont();
        NBEdgeCont& ec = nb.getEdgeCont();
        NBDistrictCont& dc = nb.getDistrictCont();
        for (std::vector<std::string>::iterator i = edges.begin(); i != edges.end(); ++i) {
            NBEdge* e = ec.retrieve(*i);
            if (e == 0) {
                WRITE_WARNING("Can not build on ramp on edge '" + *i + "' - the edge is not known.");
                continue;
            }
            NBNode* from = e->getFromNode();
            if (from->getIncomingEdges().size() == 2 && from->getOutgoingEdges().size() == 1) {
                buildOnRamp(from, nc, ec, dc, rampLength, dontSplit, incremented);
            }
            // load edge again to check offramps
            e = ec.retrieve(*i);
            if (e == 0) {
                WRITE_WARNING("Can not build off ramp on edge '" + *i + "' - the edge is not known.");
                continue;
            }
            NBNode* to = e->getToNode();
            if (to->getIncomingEdges().size() == 1 && to->getOutgoingEdges().size() == 2) {
                buildOffRamp(to, nc, ec, dc, rampLength, dontSplit, incremented);
            }
        }
    }
}
// ===========================================================================
// method definitions
// ===========================================================================
// ---------------------------------------------------------------------------
// static methods
// ---------------------------------------------------------------------------
void
NWWriter_MATSim::writeNetwork(const OptionsCont& oc, NBNetBuilder& nb) {
    // check whether a matsim-file shall be generated
    if (!oc.isSet("matsim-output")) {
        return;
    }
    OutputDevice& device = OutputDevice::getDevice(oc.getString("matsim-output"));
    device << "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n";
    device << "<!DOCTYPE network SYSTEM \"http://www.matsim.org/files/dtd/network_v1.dtd\">\n\n";
    device << "<network name=\"NAME\">\n"; // !!! name
    // write nodes
    device << "   <nodes>\n";
    NBNodeCont& nc = nb.getNodeCont();
    for (std::map<std::string, NBNode*>::const_iterator i = nc.begin(); i != nc.end(); ++i) {
        device << "      <node id=\"" << (*i).first
               << "\" x=\"" << (*i).second->getPosition().x()
               << "\" y=\"" << (*i).second->getPosition().y()
               << "\"/>\n";
    }
    device << "   </nodes>\n";
    // write edges
    device << "   <links capperiod=\"01:00:00\">\n";
    NBEdgeCont& ec = nb.getEdgeCont();
    for (std::map<std::string, NBEdge*>::const_iterator i = ec.begin(); i != ec.end(); ++i) {
        device << "      <link id=\"" << (*i).first
               << "\" from=\"" << (*i).second->getFromNode()->getID()
               << "\" to=\"" << (*i).second->getToNode()->getID()
               << "\" length=\"" << (*i).second->getLoadedLength()
               << "\" capacity=\"" << (oc.getFloat("lanes-from-capacity.norm") * (*i).second->getNumLanes())
               << "\" freespeed=\"" << (*i).second->getSpeed()
               << "\" permlanes=\"" << (*i).second->getNumLanes()
               << "\"/>\n";
    }
    device << "   </links>\n";
    //
    device << "</network>\n"; // !!! name
    device.close();
}
Exemple #12
0
void
NWFrame::writeNetwork(const OptionsCont& oc, NBNetBuilder& nb) {
    NWWriter_SUMO::writeNetwork(oc, nb);
    NWWriter_MATSim::writeNetwork(oc, nb);
    NWWriter_OpenDrive::writeNetwork(oc, nb);
    NWWriter_DlrNavteq::writeNetwork(oc, nb);
    NWWriter_XML::writeNetwork(oc, nb);
    // save the mapping information when wished
    if (oc.isSet("map-output")) {
        OutputDevice& mdevice = OutputDevice::getDevice(oc.getString("map-output"));
        mdevice << nb.getJoinedEdgesMap();
        mdevice.close();
    }
}
Exemple #13
0
// ---------------------------------------------------------------------------
// static methods
// ---------------------------------------------------------------------------
void
NWWriter_DlrNavteq::writeNetwork(const OptionsCont& oc, NBNetBuilder& nb) {
    // check whether a matsim-file shall be generated
    if (!oc.isSet("dlr-navteq-output")) {
        return;
    }
    std::map<NBEdge*, std::string> internalNodes;
    writeNodesUnsplitted(oc, nb.getNodeCont(), nb.getEdgeCont(), internalNodes);
    writeLinksUnsplitted(oc, nb.getEdgeCont(), internalNodes);
    writeTrafficSignals(oc, nb.getNodeCont());
    writeProhibitedManoeuvres(oc, nb.getNodeCont(), nb.getEdgeCont());
    writeConnectedLanes(oc, nb.getNodeCont());
}
Exemple #14
0
// ===========================================================================
// method definitions
// ===========================================================================
// ---------------------------------------------------------------------------
// static methods
// ---------------------------------------------------------------------------
void
NWWriter_XML::writeNetwork(const OptionsCont& oc, NBNetBuilder& nb) {
    // check whether plain-output files shall be generated
    if (oc.isSet("plain-output-prefix")) {
        writeNodes(oc, nb.getNodeCont());
        writeEdgesAndConnections(oc, nb.getNodeCont(), nb.getEdgeCont());
        writeTrafficLights(oc, nb.getTLLogicCont(), nb.getEdgeCont());
    }
    if (oc.isSet("junctions.join-output")) {
        writeJoinedJunctions(oc, nb.getNodeCont());
    }
    if (oc.isSet("street-sign-output")) {
        writeStreetSigns(oc, nb.getEdgeCont());
    }
}
// ===========================================================================
// 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"));
    device.writeXMLHeader("net", NWFrame::MAJOR_VERSION + " xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:noNamespaceSchemaLocation=\"http://sumo.sf.net/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
    writeLocation(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)
    for (std::map<std::string, NBNode*>::const_iterator i = nc.begin(); i != nc.end(); ++i) {
        writeJunction(device, *(*i).second);
    }
    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();
        }
    }
    // 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
    const std::vector<EdgeVector>& roundabouts = nb.getRoundabouts();
    for (std::vector<EdgeVector>::const_iterator i = roundabouts.begin(); i != roundabouts.end(); ++i) {
        writeRoundabout(device, *i);
    }
    if (roundabouts.size() != 0) {
        device.lf();
    }

    // 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();
}
// ===========================================================================
// 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();
    }
}
Exemple #17
0
/* -------------------------------------------------------------------------
 * main
 * ----------------------------------------------------------------------- */
int
main(int argc, char** argv) {
    OptionsCont& oc = OptionsCont::getOptions();
    // give some application descriptions
    oc.setApplicationDescription("Network importer / builder for the microscopic, multi-modal traffic simulation SUMO.");
    oc.setApplicationName("netconvert", "Eclipse SUMO netconvert Version " VERSION_STRING);
    int ret = 0;
    try {
        XMLSubSys::init();
        fillOptions();
        OptionsIO::setArgs(argc, argv);
        OptionsIO::getOptions();
        if (oc.processMetaOptions(argc < 2)) {
            SystemFrame::close();
            return 0;
        }
        XMLSubSys::setValidation(oc.getString("xml-validation"), oc.getString("xml-validation.net"));
        MsgHandler::initOutputOptions();
        if (!checkOptions()) {
            throw ProcessError();
        }
        RandHelper::initRandGlobal();
        // build the projection
        if (!GeoConvHelper::init(oc)) {
            throw ProcessError("Could not build projection!");
        }
        NBNetBuilder nb;
        nb.applyOptions(oc);
        // load data
        NILoader nl(nb);
        nl.load(oc);
        if (oc.getBool("ignore-errors")) {
            MsgHandler::getErrorInstance()->clear();
        }
        // check whether any errors occurred
        if (MsgHandler::getErrorInstance()->wasInformed()) {
            throw ProcessError();
        }
        nb.compute(oc);
        // check whether any errors occurred
        if (MsgHandler::getErrorInstance()->wasInformed()) {
            throw ProcessError();
        }
        NWFrame::writeNetwork(oc, nb);
    } catch (const ProcessError& e) {
        if (std::string(e.what()) != std::string("Process Error") && std::string(e.what()) != std::string("")) {
            WRITE_ERROR(e.what());
        }
        MsgHandler::getErrorInstance()->inform("Quitting (on error).", false);
        ret = 1;
#ifndef _DEBUG
    } catch (const std::exception& e) {
        if (std::string(e.what()) != std::string("")) {
            WRITE_ERROR(e.what());
        }
        MsgHandler::getErrorInstance()->inform("Quitting (on error).", false);
        ret = 1;
    } catch (...) {
        MsgHandler::getErrorInstance()->inform("Quitting (on unknown error).", false);
        ret = 1;
#endif
    }
    DistributionCont::clear();
    SystemFrame::close();
    // report about ending
    if (ret == 0) {
        std::cout << "Success." << std::endl;
    }
    return ret;
}
Exemple #18
0
// ===========================================================================
// method definitions
// ===========================================================================
// ---------------------------------------------------------------------------
// static methods
// ---------------------------------------------------------------------------
void
NWWriter_Amitran::writeNetwork(const OptionsCont& oc, NBNetBuilder& nb) {
    // check whether an amitran-file shall be generated
    if (!oc.isSet("amitran-output")) {
        return;
    }
    OutputDevice& device = OutputDevice::getDevice(oc.getString("amitran-output"));
    device << "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n";
    device << "<network xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:noNamespaceSchemaLocation=\"http://sumo-sim.org/xsd/amitran/network.xsd\">\n";
    // write nodes
    int index = 0;
    NBNodeCont& nc = nb.getNodeCont();
    std::set<NBNode*> singleRoundaboutNodes;
    std::set<NBNode*> multiRoundaboutNodes;
    const std::vector<EdgeVector>& roundabouts = nb.getRoundabouts();
    for (std::vector<EdgeVector>::const_iterator i = roundabouts.begin(); i != roundabouts.end(); ++i) {
        for (EdgeVector::const_iterator j = (*i).begin(); j != (*i).end(); ++j) {
            if ((*j)->getNumLanes() > 1) {
                multiRoundaboutNodes.insert((*j)->getFromNode());
            } else {
                singleRoundaboutNodes.insert((*j)->getFromNode());
            }
        }
    }
    std::map<NBNode*, int> nodeIds;
    for (std::map<std::string, NBNode*>::const_iterator i = nc.begin(); i != nc.end(); ++i) {
        device << "    <node id=\"" << index;
        nodeIds[i->second] = index++;
        if (singleRoundaboutNodes.count(i->second) > 0) {
            device << "\" type=\"roundaboutSingle\"/>\n";
            continue;
        }
        if (multiRoundaboutNodes.count(i->second) > 0) {
            device << "\" type=\"roundaboutMulti\"/>\n";
            continue;
        }
        switch (i->second->getType()) {
            case NODETYPE_TRAFFIC_LIGHT:
            case NODETYPE_TRAFFIC_LIGHT_NOJUNCTION:
                device << "\" type=\"trafficLight";
                break;
            case NODETYPE_PRIORITY:
                device << "\" type=\"priority";
                break;
            case NODETYPE_PRIORITY_STOP:
                device << "\" type=\"priorityStop";
                break;
            case NODETYPE_RIGHT_BEFORE_LEFT:
                device << "\" type=\"rightBeforeLeft";
                break;
            case NODETYPE_ALLWAY_STOP:
                device << "\" type=\"allwayStop";
                break;
            case NODETYPE_DEAD_END:
            case NODETYPE_DEAD_END_DEPRECATED:
                device << "\" type=\"deadEnd";
                break;
            case NODETYPE_DISTRICT:
            case NODETYPE_NOJUNCTION:
            case NODETYPE_INTERNAL:
            case NODETYPE_UNKNOWN:
                break;
        }
        device << "\"/>\n";
    }
    // write edges
    index = 0;
    NBEdgeCont& ec = nb.getEdgeCont();
    for (std::map<std::string, NBEdge*>::const_iterator i = ec.begin(); i != ec.end(); ++i) {
        device << "    <link id=\"" << index++
               << "\" from=\"" << nodeIds[i->second->getFromNode()]
               << "\" to=\"" << nodeIds[i->second->getToNode()]
               << "\" roadClass=\"" << NWWriter_DlrNavteq::getRoadClass((*i).second)
               << "\" length=\"" << int(1000 * i->second->getLoadedLength())
               << "\" speedLimitKmh=\"" << int(3.6 * (*i).second->getSpeed() + 0.5)
               << "\" laneNr=\"" << (*i).second->getNumLanes()
               << "\"/>\n";
    }
    device << "</network>\n";
    device.close();
}
Exemple #19
0
// ===========================================================================
// 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();
}
// ===========================================================================
// method definitions
// ===========================================================================
// ---------------------------------------------------------------------------
// static methods
// ---------------------------------------------------------------------------
void
NWWriter_OpenDrive::writeNetwork(const OptionsCont& oc, NBNetBuilder& nb) {
    // check whether an opendrive-file shall be generated
    if (!oc.isSet("opendrive-output")) {
        return;
    }
    const NBNodeCont& nc = nb.getNodeCont();
    const NBEdgeCont& ec = nb.getEdgeCont();
    const bool origNames = oc.getBool("output.original-names");
    const SUMOReal straightThresh = DEG2RAD(oc.getFloat("opendrive-output.straight-threshold"));
    // some internal mapping containers
    int nodeID = 1;
    int edgeID = nc.size() * 10; // distinct from node ids
    StringBijection<int> edgeMap;
    StringBijection<int> nodeMap;
    //
    OutputDevice& device = OutputDevice::getDevice(oc.getString("opendrive-output"));
    device << "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n";
    device.openTag("OpenDRIVE");
    time_t now = time(0);
    std::string dstr(ctime(&now));
    const Boundary& b = GeoConvHelper::getFinal().getConvBoundary();
    // write header
    device.openTag("header");
    device.writeAttr("revMajor", "1");
    device.writeAttr("revMinor", "4");
    device.writeAttr("name", "");
    device.writeAttr("version", "1.00");
    device.writeAttr("date", dstr.substr(0, dstr.length() - 1));
    device.writeAttr("north", b.ymax());
    device.writeAttr("south", b.ymin());
    device.writeAttr("east", b.xmax());
    device.writeAttr("west", b.xmin());
    /* @note obsolete in 1.4
    device.writeAttr("maxRoad", ec.size());
    device.writeAttr("maxJunc", nc.size());
    device.writeAttr("maxPrg", 0);
    */
    device.closeTag();

    // write normal edges (road)
    for (std::map<std::string, NBEdge*>::const_iterator i = ec.begin(); i != ec.end(); ++i) {
        const NBEdge* e = (*i).second;

        // buffer output because some fields are computed out of order
        OutputDevice_String elevationOSS(false, 3);
        elevationOSS.setPrecision(8);
        OutputDevice_String planViewOSS(false, 2);
        planViewOSS.setPrecision(8);
        SUMOReal length = 0;

        planViewOSS.openTag("planView");
        planViewOSS.setPrecision(8); // geometry hdg requires higher precision
        // for the shape we need to use the leftmost border of the leftmost lane
        const std::vector<NBEdge::Lane>& lanes = e->getLanes();
        PositionVector ls = getLeftLaneBorder(e);
#ifdef DEBUG_SMOOTH_GEOM
        if (DEBUGCOND) {
            std::cout << "write planview for edge " << e->getID() << "\n";
        }
#endif

        if (ls.size() == 2 || e->getPermissions() == SVC_PEDESTRIAN) {
            // foot paths may contain sharp angles
            length = writeGeomLines(ls, planViewOSS, elevationOSS);
        } else {
            bool ok = writeGeomSmooth(ls, e->getSpeed(), planViewOSS, elevationOSS, straightThresh, length);
            if (!ok) {
                WRITE_WARNING("Could not compute smooth shape for edge '" + e->getID() + "'.");
            }
        }
        planViewOSS.closeTag();

        device.openTag("road");
        device.writeAttr("name", StringUtils::escapeXML(e->getStreetName()));
        device.setPrecision(8); // length requires higher precision
        device.writeAttr("length", MAX2(POSITION_EPS, length));
        device.setPrecision(OUTPUT_ACCURACY); 
        device.writeAttr("id", getID(e->getID(), edgeMap, edgeID));
        device.writeAttr("junction", -1);
        const bool hasSucc = e->getConnections().size() > 0;
        const bool hasPred = e->getIncomingEdges().size() > 0;
        if (hasPred || hasSucc) {
            device.openTag("link");
            if (hasPred) {
                device.openTag("predecessor");
                device.writeAttr("elementType", "junction");
                device.writeAttr("elementId", getID(e->getFromNode()->getID(), nodeMap, nodeID));
                device.closeTag();
            }
            if (hasSucc) {
                device.openTag("successor");
                device.writeAttr("elementType", "junction");
                device.writeAttr("elementId", getID(e->getToNode()->getID(), nodeMap, nodeID));
                device.closeTag();
            }
            device.closeTag();
        }
        device.openTag("type").writeAttr("s", 0).writeAttr("type", "town").closeTag();
        device << planViewOSS.getString();
        writeElevationProfile(ls, device, elevationOSS);
        device << "        <lateralProfile/>\n";
        device << "        <lanes>\n";
        device << "            <laneSection s=\"0\">\n";
        writeEmptyCenterLane(device, "solid", 0.13);
        device << "                <right>\n";
        for (int j = e->getNumLanes(); --j >= 0;) {
            device << "                    <lane id=\"-" << e->getNumLanes() - j << "\" type=\"" << getLaneType(e->getPermissions(j)) << "\" level=\"true\">\n";
            device << "                        <link/>\n";
            // this could be used for geometry-link junctions without u-turn,
            // predecessor and sucessors would be lane indices,
            // road predecessor / succesfors would be of type 'road' rather than
            // 'junction'
            //device << "                            <predecessor id=\"-1\"/>\n";
            //device << "                            <successor id=\"-1\"/>\n";
            //device << "                        </link>\n";
            device << "                        <width sOffset=\"0\" a=\"" << e->getLaneWidth(j) << "\" b=\"0\" c=\"0\" d=\"0\"/>\n";
            std::string markType = "broken";
            if (j == 0) {
                markType = "solid";
            }
            device << "                        <roadMark sOffset=\"0\" type=\"" << markType << "\" weight=\"standard\" color=\"standard\" width=\"0.13\"/>\n";
            device << "                        <speed sOffset=\"0\" max=\"" << lanes[j].speed << "\"/>\n";
            device << "                    </lane>\n";
        }
        device << "                 </right>\n";
        device << "            </laneSection>\n";
        device << "        </lanes>\n";
        device << "        <objects/>\n";
        device << "        <signals/>\n";
        if (origNames) {
            device << "        <userData code=\"sumoId\" value=\"" << e->getID() << "\"/>\n";
        }
        device.closeTag();
        checkLaneGeometries(e);
    }
    device.lf();

    // write junction-internal edges (road). In OpenDRIVE these are called 'paths' or 'connecting roads'
    for (std::map<std::string, NBNode*>::const_iterator i = nc.begin(); i != nc.end(); ++i) {
        NBNode* n = (*i).second;
        const std::vector<NBEdge*>& incoming = (*i).second->getIncomingEdges();
        for (std::vector<NBEdge*>::const_iterator j = incoming.begin(); j != incoming.end(); ++j) {
            const NBEdge* inEdge = *j;
            const std::vector<NBEdge::Connection>& elv = inEdge->getConnections();
            for (std::vector<NBEdge::Connection>::const_iterator k = elv.begin(); k != elv.end(); ++k) {
                const NBEdge::Connection& c = *k;
                const NBEdge* outEdge = c.toEdge;
                if (outEdge == 0) {
                    continue;
                }
                const SUMOReal width = c.toEdge->getLaneWidth(c.toLane);
                const PositionVector begShape = getLeftLaneBorder(inEdge, c.fromLane);
                const PositionVector endShape = getLeftLaneBorder(outEdge, c.toLane);
                //std::cout << "computing reference line for internal lane " << c.getInternalLaneID() << " begLane=" << inEdge->getLaneShape(c.fromLane) << " endLane=" << outEdge->getLaneShape(c.toLane) << "\n";

                SUMOReal length;
                PositionVector fallBackShape;
                fallBackShape.push_back(begShape.back());
                fallBackShape.push_back(endShape.front());
                const bool turnaround = inEdge->isTurningDirectionAt(outEdge);
                bool ok = true;
                PositionVector init = NBNode::bezierControlPoints(begShape, endShape, turnaround, 25, 25, ok, 0, straightThresh);
                if (init.size() == 0) {
                    length = fallBackShape.length2D();
                    // problem with turnarounds is known, method currently returns 'ok' (#2539)
                    if (!ok) {
                        WRITE_WARNING("Could not compute smooth shape from lane '" + inEdge->getLaneID(c.fromLane) + "' to lane '" + outEdge->getLaneID(c.toLane) + "'. Use option 'junctions.scurve-stretch' or increase radius of junction '" + inEdge->getToNode()->getID() + "' to fix this.");
                    }
                } else {
                    length = bezier(init, 12).length2D();
                }

                device.openTag("road");
                device.writeAttr("name", c.getInternalLaneID());
                device.setPrecision(8); // length requires higher precision
                device.writeAttr("length", MAX2(POSITION_EPS, length));
                device.setPrecision(OUTPUT_ACCURACY); 
                device.writeAttr("id", getID(c.getInternalLaneID(), edgeMap, edgeID));
                device.writeAttr("junction", getID(n->getID(), nodeMap, nodeID));
                device.openTag("link");
                device.openTag("predecessor");
                device.writeAttr("elementType", "road");
                device.writeAttr("elementId", getID(inEdge->getID(), edgeMap, edgeID));
                device.writeAttr("contactPoint", "end");
                device.closeTag();
                device.openTag("successor");
                device.writeAttr("elementType", "road");
                device.writeAttr("elementId", getID(outEdge->getID(), edgeMap, edgeID));
                device.writeAttr("contactPoint", "start");
                device.closeTag();
                device.closeTag();
                device.openTag("type").writeAttr("s", 0).writeAttr("type", "town").closeTag();
                device.openTag("planView");
                device.setPrecision(8); // geometry hdg requires higher precision
                OutputDevice_String elevationOSS(false, 3);
#ifdef DEBUG_SMOOTH_GEOM
                if (DEBUGCOND) {
                    std::cout << "write planview for internal edge " << c.getInternalLaneID() << " init=" << init << " fallback=" << fallBackShape << "\n";
                }
#endif
                if (init.size() == 0) {
                    writeGeomLines(fallBackShape, device, elevationOSS);
                } else {
                    writeGeomPP3(device, elevationOSS, init, length);
                }
                device.setPrecision(OUTPUT_ACCURACY);
                device.closeTag();
                writeElevationProfile(fallBackShape, device, elevationOSS);
                device << "        <lateralProfile/>\n";
                device << "        <lanes>\n";
                device << "            <laneSection s=\"0\">\n";
                writeEmptyCenterLane(device, "none", 0);
                device << "                <right>\n";
                device << "                    <lane id=\"-1\" type=\"" << getLaneType(outEdge->getPermissions(c.toLane)) << "\" level=\"true\">\n";
                device << "                        <link>\n";
                device << "                            <predecessor id=\"-" << inEdge->getNumLanes() - c.fromLane << "\"/>\n";
                device << "                            <successor id=\"-" << outEdge->getNumLanes() - c.toLane << "\"/>\n";
                device << "                        </link>\n";
                device << "                        <width sOffset=\"0\" a=\"" << width << "\" b=\"0\" c=\"0\" d=\"0\"/>\n";
                device << "                        <roadMark sOffset=\"0\" type=\"none\" weight=\"standard\" color=\"standard\" width=\"0.13\"/>\n";
                device << "                    </lane>\n";
                device << "                 </right>\n";
                device << "            </laneSection>\n";
                device << "        </lanes>\n";
                device << "        <objects/>\n";
                device << "        <signals/>\n";
                device.closeTag();
            }
        }
    }

    // write junctions (junction)
    for (std::map<std::string, NBNode*>::const_iterator i = nc.begin(); i != nc.end(); ++i) {
        NBNode* n = (*i).second;
        const std::vector<NBEdge*>& incoming = n->getIncomingEdges();
        // check if any connections must be written
        int numConnections = 0;
        for (std::vector<NBEdge*>::const_iterator j = incoming.begin(); j != incoming.end(); ++j) {
            numConnections += (int)((*j)->getConnections().size());
        }
        if (numConnections == 0) {
            continue;
        }
        device << "    <junction name=\"" << n->getID() << "\" id=\"" << getID(n->getID(), nodeMap, nodeID) << "\">\n";
        int index = 0;
        for (std::vector<NBEdge*>::const_iterator j = incoming.begin(); j != incoming.end(); ++j) {
            const NBEdge* inEdge = *j;
            const std::vector<NBEdge::Connection>& elv = inEdge->getConnections();
            for (std::vector<NBEdge::Connection>::const_iterator k = elv.begin(); k != elv.end(); ++k) {
                const NBEdge::Connection& c = *k;
                const NBEdge* outEdge = c.toEdge;
                if (outEdge == 0) {
                    continue;
                }
                device << "    <connection id=\""
                       << index << "\" incomingRoad=\"" << getID(inEdge->getID(), edgeMap, edgeID)
                       << "\" connectingRoad=\""
                       << getID(c.getInternalLaneID(), edgeMap, edgeID)
                       << "\" contactPoint=\"start\">\n";
                device << "        <laneLink from=\"-" << inEdge->getNumLanes() - c.fromLane
                       << "\" to=\"-1"  // every connection has its own edge
                       << "\"/>\n";
                device << "    </connection>\n";
                ++index;
            }
        }
        device << "    </junction>\n";
    }

    device.closeTag();
    device.close();
}
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);
        }
    }
}
Exemple #23
0
// ===========================================================================
// method definitions
// ===========================================================================
// ---------------------------------------------------------------------------
// static methods
// ---------------------------------------------------------------------------
void
NWWriter_OpenDrive::writeNetwork(const OptionsCont& oc, NBNetBuilder& nb) {
    // check whether an opendrive-file shall be generated
    if (!oc.isSet("opendrive-output")) {
        return;
    }
    const NBNodeCont& nc = nb.getNodeCont();
    const NBEdgeCont& ec = nb.getEdgeCont();
    const bool origNames = oc.getBool("output.original-names");
    const bool lefthand = oc.getBool("lefthand");
    const double straightThresh = DEG2RAD(oc.getFloat("opendrive-output.straight-threshold"));
    // some internal mapping containers
    int nodeID = 1;
    int edgeID = nc.size() * 10; // distinct from node ids
    StringBijection<int> edgeMap;
    StringBijection<int> nodeMap;
    //
    OutputDevice& device = OutputDevice::getDevice(oc.getString("opendrive-output"));
    device << "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n";
    device.openTag("OpenDRIVE");
    time_t now = time(0);
    std::string dstr(ctime(&now));
    const Boundary& b = GeoConvHelper::getFinal().getConvBoundary();
    // write header
    device.openTag("header");
    device.writeAttr("revMajor", "1");
    device.writeAttr("revMinor", "4");
    device.writeAttr("name", "");
    device.writeAttr("version", "1.00");
    device.writeAttr("date", dstr.substr(0, dstr.length() - 1));
    device.writeAttr("north", b.ymax());
    device.writeAttr("south", b.ymin());
    device.writeAttr("east", b.xmax());
    device.writeAttr("west", b.xmin());
    /* @note obsolete in 1.4
    device.writeAttr("maxRoad", ec.size());
    device.writeAttr("maxJunc", nc.size());
    device.writeAttr("maxPrg", 0);
    */
    device.closeTag();
    // write optional geo reference
    const GeoConvHelper& gch = GeoConvHelper::getFinal();
    if (gch.usingGeoProjection()) {
        if (gch.getOffsetBase() == Position(0,0)) {
            device.openTag("geoReference");
            device.writePreformattedTag(" <![CDATA[\n " 
                    + gch.getProjString() 
                    + "\n]]>\n");
            device.closeTag();
        } else {
            WRITE_WARNING("Could not write OpenDRIVE geoReference. Only unshifted Coordinate systems are supported (offset=" + toString(gch.getOffsetBase()) + ")");
        }
    }

    // write normal edges (road)
    for (std::map<std::string, NBEdge*>::const_iterator i = ec.begin(); i != ec.end(); ++i) {
        const NBEdge* e = (*i).second;
        const int fromNodeID = e->getIncomingEdges().size() > 0 ? getID(e->getFromNode()->getID(), nodeMap, nodeID) : INVALID_ID;
        const int toNodeID = e->getConnections().size() > 0 ? getID(e->getToNode()->getID(), nodeMap, nodeID) : INVALID_ID;
        writeNormalEdge(device, e,
                        getID(e->getID(), edgeMap, edgeID),
                        fromNodeID, toNodeID,
                        origNames, straightThresh);
    }
    device.lf();

    // write junction-internal edges (road). In OpenDRIVE these are called 'paths' or 'connecting roads'
    OutputDevice_String junctionOSS(false, 3);
    for (std::map<std::string, NBNode*>::const_iterator i = nc.begin(); i != nc.end(); ++i) {
        NBNode* n = (*i).second;
        int connectionID = 0; // unique within a junction
        const int nID = getID(n->getID(), nodeMap, nodeID);
        if (n->numNormalConnections() > 0) {
            junctionOSS << "    <junction name=\"" << n->getID() << "\" id=\"" << nID << "\">\n";
        }
        std::vector<NBEdge*> incoming = (*i).second->getIncomingEdges();
        if (lefthand) {
            std::reverse(incoming.begin(), incoming.end());
        }
        for (NBEdge* inEdge : incoming) {
            std::string centerMark = "none";
            const int inEdgeID = getID(inEdge->getID(), edgeMap, edgeID);
            // group parallel edges
            const NBEdge* outEdge = 0;
            bool isOuterEdge = true; // determine where a solid outer border should be drawn
            int lastFromLane = -1;
            std::vector<NBEdge::Connection> parallel;
            std::vector<NBEdge::Connection> connections = inEdge->getConnections();
            if (lefthand) {
                std::reverse(connections.begin(), connections.end());
            }
            for (const NBEdge::Connection& c : connections) {
                assert(c.toEdge != 0);
                if (outEdge != c.toEdge || c.fromLane == lastFromLane) {
                    if (outEdge != 0) {
                        if (isOuterEdge) {
                            addPedestrianConnection(inEdge, outEdge, parallel);
                        }
                        connectionID = writeInternalEdge(device, junctionOSS, inEdge, nID,
                                                         getID(parallel.back().getInternalLaneID(), edgeMap, edgeID),
                                                         inEdgeID,
                                                         getID(outEdge->getID(), edgeMap, edgeID),
                                                         connectionID,
                                                         parallel, isOuterEdge, straightThresh, centerMark);
                        parallel.clear();
                        isOuterEdge = false;
                    }
                    outEdge = c.toEdge;
                }
                lastFromLane = c.fromLane;
                parallel.push_back(c);
            }
            if (isOuterEdge) {
                addPedestrianConnection(inEdge, outEdge, parallel);
            }
            if (!parallel.empty()) {
                if (!lefthand && (n->geometryLike() || inEdge->isTurningDirectionAt(outEdge))) {
                    centerMark = "solid";
                }
                connectionID = writeInternalEdge(device, junctionOSS, inEdge, nID,
                                                 getID(parallel.back().getInternalLaneID(), edgeMap, edgeID),
                                                 inEdgeID,
                                                 getID(outEdge->getID(), edgeMap, edgeID),
                                                 connectionID,
                                                 parallel, isOuterEdge, straightThresh, centerMark);
                parallel.clear();
            }
        }
        if (n->numNormalConnections() > 0) {
            junctionOSS << "    </junction>\n";
        }
    }
    device.lf();
    // write junctions (junction)
    device << junctionOSS.getString();

    for (std::map<std::string, NBNode*>::const_iterator i = nc.begin(); i != nc.end(); ++i) {
        NBNode* n = (*i).second;
        const std::vector<NBEdge*>& incoming = n->getIncomingEdges();
        // check if any connections must be written
        int numConnections = 0;
        for (std::vector<NBEdge*>::const_iterator j = incoming.begin(); j != incoming.end(); ++j) {
            numConnections += (int)((*j)->getConnections().size());
        }
        if (numConnections == 0) {
            continue;
        }
        for (std::vector<NBEdge*>::const_iterator j = incoming.begin(); j != incoming.end(); ++j) {
            const NBEdge* inEdge = *j;
            const std::vector<NBEdge::Connection>& elv = inEdge->getConnections();
            for (std::vector<NBEdge::Connection>::const_iterator k = elv.begin(); k != elv.end(); ++k) {
                const NBEdge::Connection& c = *k;
                const NBEdge* outEdge = c.toEdge;
                if (outEdge == 0) {
                    continue;
                }
            }
        }
    }

    device.closeTag();
    device.close();
}
Exemple #24
0
FXint
GNELoadThread::run() {
    // register message callbacks
    MsgHandler::getMessageInstance()->addRetriever(myMessageRetriever);
    MsgHandler::getErrorInstance()->addRetriever(myErrorRetriever);
    MsgHandler::getWarningInstance()->addRetriever(myWarningRetriever);

    GNENet* net = 0;

    // try to load the given configuration
    OptionsCont& oc = OptionsCont::getOptions();
    oc.clear();
    if (!initOptions()) {
        submitEndAndCleanup(net);
        return 0;
    }
    MsgHandler::initOutputOptions();
    if (!(NIFrame::checkOptions() &&
            NBFrame::checkOptions() &&
            NWFrame::checkOptions())) {
        // options are not valid
        WRITE_ERROR("Invalid Options. Nothing loaded");
        submitEndAndCleanup(net);
        return 0;
    }
    MsgHandler::getErrorInstance()->clear();
    MsgHandler::getWarningInstance()->clear();
    MsgHandler::getMessageInstance()->clear();

    RandHelper::initRandGlobal();
    if (!GeoConvHelper::init(oc)) {
        WRITE_ERROR("Could not build projection!");
        submitEndAndCleanup(net);
        return 0;
    }
    XMLSubSys::setValidation(oc.getString("xml-validation"), oc.getString("xml-validation.net"));
    // this netbuilder instance becomes the responsibility of the GNENet
    NBNetBuilder* netBuilder = new NBNetBuilder();

    netBuilder->applyOptions(oc);

    if (myNewNet) {
        // create new network
        net = new GNENet(netBuilder);
    } else {
        NILoader nl(*netBuilder);
        try {
            nl.load(oc);

            if (!myLoadNet) {
                WRITE_MESSAGE("Performing initial computation ...\n");
                // perform one-time processing (i.e. edge removal)
                netBuilder->compute(oc);
                // @todo remove one-time processing options!
            } else {
                // make coordinate conversion usable before first netBuilder->compute()
                GeoConvHelper::computeFinal();
            }

            if (oc.getBool("ignore-errors")) {
                MsgHandler::getErrorInstance()->clear();
            }

            // check whether any errors occured
            if (MsgHandler::getErrorInstance()->wasInformed()) {
                throw ProcessError();
            } else {
                net = new GNENet(netBuilder);
            }

        } catch (ProcessError& e) {
            if (std::string(e.what()) != std::string("Process Error") && std::string(e.what()) != std::string("")) {
                WRITE_ERROR(e.what());
            }
            WRITE_ERROR("Failed to build network.");
            delete net;
            delete netBuilder;
            net = 0;
        } catch (std::exception& e) {
            WRITE_ERROR(e.what());
#ifdef _DEBUG
            throw;
#endif
            delete net;
            delete netBuilder;
            net = 0;
        }
    }
    // only a single setting file is supported
    submitEndAndCleanup(net, oc.getString("gui-settings-file"), oc.getBool("registry-viewport"));
    return 0;
}
Exemple #25
0
// ===========================================================================
// 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;
    }
}