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; }
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*) ¤tEdge, 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; }