Esempio n. 1
0
int main (int argc, char *argv[]) {
    if(argc <= 1) {
        cerr << "usage: " << endl << argv[0] << " <osrm-data>" << endl;
        exit(-1);
    }

    unsigned numberOfThreads = omp_get_num_procs();
    if(testDataFile("contractor.ini")) {
        ContractorConfiguration contractorConfig("contractor.ini");
        if(atoi(contractorConfig.GetParameter("Threads").c_str()) != 0 && (unsigned)atoi(contractorConfig.GetParameter("Threads").c_str()) <= numberOfThreads)
            numberOfThreads = (unsigned)atoi( contractorConfig.GetParameter("Threads").c_str() );
    }
    omp_set_num_threads(numberOfThreads);

    cout << "preprocessing data from input file " << argv[1];
#ifdef _GLIBCXX_PARALLEL
    cout << " using STL parallel mode" << std::endl;
#else
    cout << " using STL serial mode" << std::endl;
#endif

    ifstream in;
    in.open (argv[1]);
    if (!in.is_open()) {
        cerr << "Cannot open " << argv[1] << endl; exit(-1);
    }
    vector<ImportEdge> edgeList;
    const NodeID n = readBinaryOSRMGraphFromStream(in, edgeList, int2ExtNodeMap);
    in.close();

    char nodeOut[1024];
    char edgeOut[1024];
    char ramIndexOut[1024];
    char fileIndexOut[1024];
    char levelInfoOut[1024];
    strcpy(nodeOut, argv[1]);
    strcpy(edgeOut, argv[1]);
    strcpy(ramIndexOut, argv[1]);
    strcpy(fileIndexOut, argv[1]);
    strcpy(levelInfoOut, argv[1]);

    strcat(nodeOut, ".nodes");
    strcat(edgeOut, ".hsgr");
    strcat(ramIndexOut, ".ramIndex");
    strcat(fileIndexOut, ".fileIndex");
    strcat(levelInfoOut, ".levels");

    cout << "initializing contractor ..." << flush;
    Contractor* contractor = new Contractor( n, edgeList );
    contractor->Run();

    LevelInformation * levelInfo = contractor->GetLevelInformation();
    std::cout << "sorting level info" << std::endl;
    for(unsigned currentLevel = levelInfo->GetNumberOfLevels(); currentLevel>0; currentLevel--) {
        std::vector<unsigned> & level = levelInfo->GetLevel(currentLevel-1);
        std::sort(level.begin(), level.end());
    }

    std::cout << "writing level info" << std::endl;
    ofstream levelOutFile(levelInfoOut, ios::binary);
    unsigned numberOfLevels = levelInfo->GetNumberOfLevels();
    levelOutFile.write((char *)&numberOfLevels, sizeof(unsigned));
    for(unsigned currentLevel = 0; currentLevel < levelInfo->GetNumberOfLevels(); currentLevel++ ) {
        std::vector<unsigned> & level = levelInfo->GetLevel(currentLevel);
        unsigned sizeOfLevel = level.size();
        levelOutFile.write((char *)&sizeOfLevel, sizeof(unsigned));
        for(unsigned currentLevelEntry = 0; currentLevelEntry < sizeOfLevel; currentLevelEntry++) {
            unsigned node = level[currentLevelEntry];
            levelOutFile.write((char *)&node, sizeof(unsigned));
            assert(node < n);
        }
    }
    levelOutFile.close();
    std::vector< ContractionCleanup::Edge > contractedEdges;
    contractor->GetEdges( contractedEdges );
    delete contractor;

    ContractionCleanup * cleanup = new ContractionCleanup(n, contractedEdges);
    contractedEdges.clear();
    cleanup->Run();

    std::vector< InputEdge> cleanedEdgeList;
    cleanup->GetData(cleanedEdgeList);
    delete cleanup;

    cout << "Serializing edges " << flush;
    ofstream edgeOutFile(edgeOut, ios::binary);
    Percent p(cleanedEdgeList.size());
    for(std::vector< InputEdge>::iterator it = cleanedEdgeList.begin(); it != cleanedEdgeList.end(); it++) {
        p.printIncrement();
        int distance= it->data.distance;
        assert(distance > 0);
        bool shortcut= it->data.shortcut;
        bool forward= it->data.forward;
        bool backward= it->data.backward;
        NodeID middle;
        if(shortcut)
            middle = it->data.middleName.middle;
        else {
            middle = it->data.middleName.nameID;
        }

        NodeID source = it->source;
        NodeID target = it->target;
        short type = it->data.type;

        edgeOutFile.write((char *)&(distance), sizeof(int));
        edgeOutFile.write((char *)&(shortcut), sizeof(bool));
        edgeOutFile.write((char *)&(forward), sizeof(bool));
        edgeOutFile.write((char *)&(backward), sizeof(bool));
        edgeOutFile.write((char *)&(middle), sizeof(NodeID));
        edgeOutFile.write((char *)&(type), sizeof(short));
        edgeOutFile.write((char *)&(source), sizeof(NodeID));
        edgeOutFile.write((char *)&(target), sizeof(NodeID));
    }
    edgeOutFile.close();
    cleanedEdgeList.clear();

    std::cout << "writing node map ..." << std::flush;
    ofstream mapOutFile(nodeOut, ios::binary);

    for(NodeID i = 0; i < int2ExtNodeMap->size(); i++) {
        mapOutFile.write((char *)&(int2ExtNodeMap->at(i)), sizeof(NodeInfo));
    }
    mapOutFile.close();
    std::cout << "ok" << std::endl;

    WritableGrid * writeableGrid = new WritableGrid();
    cout << "building grid ..." << flush;
    writeableGrid->ConstructGrid(edgeList, int2ExtNodeMap, ramIndexOut, fileIndexOut);
    delete writeableGrid;

    int2ExtNodeMap->clear();
    delete int2ExtNodeMap;

    cout << "finished" << endl;
    return 0;
}
Esempio n. 2
0
int main (int argc, char *argv[]) {
    if(argc < 3) {
        ERR("usage: " << std::endl << argv[0] << " <osrm-data> <osrm-restrictions>");
    }

    double startupTime = get_timestamp();
    unsigned numberOfThreads = omp_get_num_procs();
    std::string SRTM_ROOT;
    if(testDataFile("contractor.ini")) {
        ContractorConfiguration contractorConfig("contractor.ini");
        if(atoi(contractorConfig.GetParameter("Threads").c_str()) != 0 && (unsigned)atoi(contractorConfig.GetParameter("Threads").c_str()) <= numberOfThreads)
            numberOfThreads = (unsigned)atoi( contractorConfig.GetParameter("Threads").c_str() );
        if(0 < contractorConfig.GetParameter("SRTM").size() )
            SRTM_ROOT = contractorConfig.GetParameter("SRTM");
    }
    if(0 != SRTM_ROOT.size())
        INFO("Loading SRTM from/to " << SRTM_ROOT);
    omp_set_num_threads(numberOfThreads);

    INFO("preprocessing data from input file " << argv[2] << " using STL "
#ifdef _GLIBCXX_PARALLEL
            "parallel (GCC)"
#else
            "serial"
#endif
            " mode");

    INFO("Using restrictions from file: " << argv[2]);
    std::ifstream restrictionsInstream(argv[2], ios::binary);
    _Restriction restriction;
    unsigned usableRestrictionsCounter(0);
    restrictionsInstream.read((char*)&usableRestrictionsCounter, sizeof(unsigned));
    for(unsigned i = 0; i < usableRestrictionsCounter; ++i) {
        restrictionsInstream.read((char *)&(restriction), sizeof(_Restriction));
        inputRestrictions.push_back(restriction);
    }
    restrictionsInstream.close();


    ifstream in;
    in.open (argv[1], ifstream::in | ifstream::binary);
    if (!in.is_open()) {
        ERR("Cannot open " << argv[1]);
    }

    char nodeOut[1024];    		strcpy(nodeOut, argv[1]);    		strcat(nodeOut, ".nodes");
    char edgeOut[1024];    		strcpy(edgeOut, argv[1]);    		strcat(edgeOut, ".hsgr");
    char ramIndexOut[1024];    	strcpy(ramIndexOut, argv[1]);    	strcat(ramIndexOut, ".ramIndex");
    char fileIndexOut[1024];    strcpy(fileIndexOut, argv[1]);    	strcat(fileIndexOut, ".fileIndex");
    char levelInfoOut[1024];    strcpy(levelInfoOut, argv[1]);    	strcat(levelInfoOut, ".levels");

    std::vector<ImportEdge> edgeList;
    NodeID nodeBasedNodeNumber = readBinaryOSRMGraphFromStream(in, edgeList, bollardNodes, trafficLightNodes, &internalToExternaleNodeMapping, inputRestrictions);
    in.close();
    INFO("Loaded " << inputRestrictions.size() << " restrictions, " << bollardNodes.size() << " bollard nodes, " << trafficLightNodes.size() << " traffic lights");

    EdgeBasedGraphFactory * edgeBasedGraphFactory = new EdgeBasedGraphFactory (nodeBasedNodeNumber, edgeList, bollardNodes, trafficLightNodes, inputRestrictions, internalToExternaleNodeMapping, SRTM_ROOT);
    edgeList.clear();
    std::vector<ImportEdge>().swap(edgeList);

    edgeBasedGraphFactory->Run();
    NodeID edgeBasedNodeNumber = edgeBasedGraphFactory->GetNumberOfNodes();
    std::vector<EdgeBasedEdge> edgeBasedEdgeList;
    edgeBasedGraphFactory->GetEdgeBasedEdges(edgeBasedEdgeList);

    std::vector<EdgeBasedGraphFactory::EdgeBasedNode> nodeBasedEdgeList;
    edgeBasedGraphFactory->GetEdgeBasedNodes(nodeBasedEdgeList);
    DELETE(edgeBasedGraphFactory);
    double expansionHasFinishedTime = get_timestamp() - startupTime;

    WritableGrid * writeableGrid = new WritableGrid();
    INFO("building grid ...");
    writeableGrid->ConstructGrid(nodeBasedEdgeList, ramIndexOut, fileIndexOut);
    DELETE( writeableGrid );
    CRC32 crc32;
    unsigned crc32OfNodeBasedEdgeList = crc32((char *)&(nodeBasedEdgeList[0]), nodeBasedEdgeList.size()*sizeof(EdgeBasedGraphFactory::EdgeBasedNode));
//    INFO("CRC32 of data is " << crc32OfNodeBasedEdgeList);

    nodeBasedEdgeList.clear();
    std::vector<EdgeBasedGraphFactory::EdgeBasedNode>().swap(nodeBasedEdgeList);

    INFO("writing node map ...");
    std::ofstream mapOutFile(nodeOut, ios::binary);
    mapOutFile.write((char *)&(internalToExternaleNodeMapping[0]), internalToExternaleNodeMapping.size()*sizeof(NodeInfo));
    mapOutFile.close();


    std::vector<NodeInfo>().swap(internalToExternaleNodeMapping);
    inputRestrictions.clear();
    std::vector<_Restriction>().swap(inputRestrictions);

//    unsigned crc32OfNodeBasedEdgeList = crc32((char*)&edgeBasedEdgeList[0], edgeBasedEdgeList.size());
//    INFO("CRC32 of data is " << crc32OfNodeBasedEdgeList);

    INFO("initializing contractor");
    Contractor* contractor = new Contractor( edgeBasedNodeNumber, edgeBasedEdgeList );
    double contractionStartedTimestamp(get_timestamp());
    contractor->Run();
    INFO("Contraction took " << get_timestamp() - contractionStartedTimestamp << " sec");

    std::vector< ContractionCleanup::Edge > contractedEdges;
    contractor->GetEdges( contractedEdges );
    delete contractor;

    ContractionCleanup * cleanup = new ContractionCleanup(edgeBasedNodeNumber, contractedEdges);
    contractedEdges.clear();
    std::vector<ContractionCleanup::Edge>().swap(contractedEdges);
    cleanup->Run();

    std::vector< InputEdge> cleanedEdgeList;
    cleanup->GetData(cleanedEdgeList);
    DELETE( cleanup );

    INFO("Building Node Array");
    sort(cleanedEdgeList.begin(), cleanedEdgeList.end());
    unsigned numberOfNodes = 0;
    unsigned numberOfEdges = cleanedEdgeList.size();
    INFO("Serializing compacted graph");
    ofstream edgeOutFile(edgeOut, ios::binary);

    BOOST_FOREACH(InputEdge & edge, cleanedEdgeList) {
        if(edge.source > numberOfNodes) {
            numberOfNodes = edge.source;
        }
        if(edge.target > numberOfNodes) {
            numberOfNodes = edge.target;
        }
    }
    numberOfNodes+=1;

    std::vector< StaticGraph<EdgeData>::_StrNode > _nodes;
    _nodes.resize( numberOfNodes + 1 );

    StaticGraph<EdgeData>::EdgeIterator edge = 0;
    StaticGraph<EdgeData>::EdgeIterator position = 0;
    for ( StaticGraph<EdgeData>::NodeIterator node = 0; node <= numberOfNodes; ++node ) {
        StaticGraph<EdgeData>::EdgeIterator lastEdge = edge;
        while ( edge < numberOfEdges && cleanedEdgeList[edge].source == node )
            ++edge;
        _nodes[node].firstEdge = position; //=edge
        position += edge - lastEdge; //remove
    }
    //Serialize numberOfNodes, nodes
    edgeOutFile.write((char*) &crc32OfNodeBasedEdgeList, sizeof(unsigned));
    edgeOutFile.write((char*) &numberOfNodes, sizeof(unsigned));
    edgeOutFile.write((char*) &_nodes[0], sizeof(StaticGraph<EdgeData>::_StrNode)*(numberOfNodes+1));

    //Serialize number of Edges
    edgeOutFile.write((char*) &position, sizeof(unsigned));

    edge = 0;
    int usedEdgeCounter = 0;
    StaticGraph<EdgeData>::_StrEdge currentEdge;
    for ( StaticGraph<EdgeData>::NodeIterator node = 0; node < numberOfNodes; ++node ) {
        for ( StaticGraph<EdgeData>::EdgeIterator i = _nodes[node].firstEdge, e = _nodes[node+1].firstEdge; i != e; ++i ) {

            currentEdge.target = cleanedEdgeList[edge].target;
            currentEdge.data = cleanedEdgeList[edge].data;
            if(currentEdge.data.distance <= 0) {
                INFO("Edge: " << i << ",source: " << cleanedEdgeList[edge].source << ", target: " << cleanedEdgeList[edge].target << ", dist: " << currentEdge.data.distance);
                ERR("Failed at edges of node " << node << " of " << numberOfNodes);
            }
            //Serialize edges
            edgeOutFile.write((char*) &currentEdge, sizeof(StaticGraph<EdgeData>::_StrEdge));
            ++edge;
            ++usedEdgeCounter;
        }
    }
    double endTime = (get_timestamp() - startupTime);
    INFO("Expansion  : " << (nodeBasedNodeNumber/expansionHasFinishedTime) << " nodes/sec and "<< (edgeBasedNodeNumber/expansionHasFinishedTime) << " edges/sec");
    INFO("Contraction: " << (edgeBasedNodeNumber/expansionHasFinishedTime) << " nodes/sec and "<< usedEdgeCounter/endTime << " edges/sec");

    edgeOutFile.close();
    cleanedEdgeList.clear();
    _nodes.clear();
    INFO("finished preprocessing");
    return 0;
}
bool ContractionHierarchies::Preprocess( IImporter* importer, QString dir )
{
	QString filename = fileInDirectory( dir, "Contraction Hierarchies" );

	std::vector< IImporter::RoutingNode > inputNodes;
	std::vector< IImporter::RoutingEdge > inputEdges;

	if ( !importer->GetRoutingNodes( &inputNodes ) )
		return false;
	if ( !importer->GetRoutingEdges( &inputEdges ) )
		return false;

	unsigned numEdges = inputEdges.size();
	unsigned numNodes = inputNodes.size();

	Contractor* contractor = new Contractor( numNodes, inputEdges );
	std::vector< IImporter::RoutingEdge >().swap( inputEdges );
	contractor->Run();

	std::vector< Contractor::Witness > witnessList;
	contractor->GetWitnessList( witnessList );

	std::vector< ContractionCleanup::Edge > contractedEdges;
	std::vector< ContractionCleanup::Edge > contractedLoops;
	contractor->GetEdges( &contractedEdges );
	contractor->GetLoops( &contractedLoops );
	delete contractor;

	ContractionCleanup* cleanup = new ContractionCleanup( inputNodes.size(), contractedEdges, contractedLoops, witnessList );
	std::vector< ContractionCleanup::Edge >().swap( contractedEdges );
	std::vector< ContractionCleanup::Edge >().swap( contractedLoops );
	std::vector< Contractor::Witness >().swap( witnessList );
	cleanup->Run();

	std::vector< CompressedGraph::Edge > edges;
	std::vector< NodeID > map;
	cleanup->GetData( &edges, &map );
	delete cleanup;

	{
		std::vector< unsigned > edgeIDs( numEdges );
		for ( unsigned edge = 0; edge < edges.size(); edge++ ) {
			if ( edges[edge].data.shortcut )
				continue;
			unsigned id = 0;
			unsigned otherEdge = edge;
			while ( true ) {
				if ( otherEdge == 0 )
					break;
				otherEdge--;
				if ( edges[otherEdge].source != edges[edge].source )
					break;
				if ( edges[otherEdge].target != edges[edge].target )
					continue;
				if ( edges[otherEdge].data.shortcut )
					continue;
				id++;
			}
			edgeIDs[edges[edge].data.id] = id;
		}
		importer->SetEdgeIDMap( edgeIDs );
	}

	std::vector< IRouter::Node > nodes( numNodes );
	for ( std::vector< IImporter::RoutingNode >::const_iterator i = inputNodes.begin(), iend = inputNodes.end(); i != iend; i++ )
		nodes[map[i - inputNodes.begin()]].coordinate = i->coordinate;
	std::vector< IImporter::RoutingNode >().swap( inputNodes );

	std::vector< IRouter::Node > pathNodes;
	{
		std::vector< IImporter::RoutingNode > edgePaths;
		if ( !importer->GetRoutingEdgePaths( &edgePaths ) )
			return false;
		pathNodes.resize( edgePaths.size() );
		for ( unsigned i = 0; i < edgePaths.size(); i++ )
			pathNodes[i].coordinate = edgePaths[i].coordinate;
	}

	if ( !importer->GetRoutingEdges( &inputEdges ) )
		return false;

	{
		std::vector< QString > inputNames;
		if ( !importer->GetRoutingWayNames( &inputNames ) )
			return false;

		QFile nameFile( filename + "_names" );
		if ( !openQFile( &nameFile, QIODevice::WriteOnly ) )
			return false;

		std::vector< unsigned > nameMap( inputNames.size() );
		for ( unsigned name = 0; name < inputNames.size(); name++ ) {
			nameMap[name] = nameFile.pos();
			QByteArray buffer = inputNames[name].toUtf8();
			buffer.push_back( ( char ) 0 );
			nameFile.write( buffer );
		}

		nameFile.close();
		nameFile.open( QIODevice::ReadOnly );
		const char* test = ( const char* ) nameFile.map( 0, nameFile.size() );
		for ( unsigned name = 0; name < inputNames.size(); name++ ) {
			QString testName = QString::fromUtf8( test + nameMap[name] );
			assert( testName == inputNames[name] );
		}

		for ( unsigned edge = 0; edge < numEdges; edge++ )
			inputEdges[edge].nameID = nameMap[inputEdges[edge].nameID];
	}

	{
		std::vector< QString > inputTypes;
		if ( !importer->GetRoutingWayTypes( &inputTypes ) )
			return false;

		QFile typeFile( filename + "_types" );
		if ( !openQFile( &typeFile, QIODevice::WriteOnly ) )
			return false;

		QStringList typeList;
		for ( unsigned type = 0; type < inputTypes.size(); type++ )
			typeList.push_back( inputTypes[type] );

		typeFile.write( typeList.join( ";" ).toUtf8() );
	}

	for ( std::vector< IImporter::RoutingEdge >::iterator i = inputEdges.begin(), iend = inputEdges.end(); i != iend; i++ ) {
		i->source = map[i->source];
		i->target = map[i->target];
	}

	CompressedGraphBuilder* builder = new CompressedGraphBuilder( 1u << m_settings.blockSize, nodes, edges, inputEdges, pathNodes );
	if ( !builder->run( filename, &map ) )
		return false;
	delete builder;

	importer->SetIDMap( map );

	return true;
}