/* open source routing machine Copyright (C) Dennis Luxen, 2010 This program is free software; you can redistribute it and/or modify it under the terms of the GNU AFFERO General Public License as published by the Free Software Foundation; either version 3 of the License, or any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA or see http://www.gnu.org/licenses/agpl.txt. */ //g++ createHierarchy.cpp -fopenmp -Wno-deprecated -o createHierarchy -O3 -march=native -DNDEBUG -I/usr/include/libxml2 -lstxxl #define VERBOSE(x) x #define VERBOSE2(x) #ifdef NDEBUG #undef VERBOSE #undef VERBOSE2 #endif #include #include #include #include #include #include #include #include "Util/OpenMPReplacement.h" #include "typedefs.h" #include "Contractor/Contractor.h" #include "Contractor/ContractionCleanup.h" #include "Contractor/EdgeBasedGraphFactory.h" #include "DataStructures/BinaryHeap.h" #include "DataStructures/ExtractorStructs.h" #include "DataStructures/NNGrid.h" #include "Util/BaseConfiguration.h" #include "Util/InputFileUtil.h" #include "Util/GraphLoader.h" #include "Util/OpenMPReplacement.h" using namespace std; typedef DynamicGraph::InputEdge InputEdge; typedef StaticGraph::InputEdge StaticEdge; typedef BaseConfiguration ContractorConfiguration; std::vector internalToExternaleNodeMapping; std::vector<_Restriction> inputRestrictions; std::vector bollardNodes; std::vector trafficLightNodes; int main (int argc, char *argv[]) { if(argc < 3) { ERR("usage: " << std::endl << argv[0] << " "); } 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 edgeList; NodeID n = 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 (n, edgeList, bollardNodes, trafficLightNodes, inputRestrictions, internalToExternaleNodeMapping, SRTM_ROOT); edgeList.clear(); std::vector().swap(edgeList); edgeBasedGraphFactory->Run(); n = edgeBasedGraphFactory->GetNumberOfNodes(); std::vector edgeBasedEdgeList; edgeBasedGraphFactory->GetEdgeBasedEdges(edgeBasedEdgeList); std::vector nodeBasedEdgeList; edgeBasedGraphFactory->GetEdgeBasedNodes(nodeBasedEdgeList); DELETE(edgeBasedGraphFactory); WritableGrid * writeableGrid = new WritableGrid(); INFO("building grid ..."); writeableGrid->ConstructGrid(nodeBasedEdgeList, ramIndexOut, fileIndexOut); DELETE( writeableGrid ); nodeBasedEdgeList.clear(); std::vector().swap(nodeBasedEdgeList); INFO("writing node map ..."); std::ofstream mapOutFile(nodeOut, ios::binary); BOOST_FOREACH(NodeInfo & info, internalToExternaleNodeMapping) { mapOutFile.write((char *)&(info), sizeof(NodeInfo)); } mapOutFile.close(); internalToExternaleNodeMapping.clear(); std::vector().swap(internalToExternaleNodeMapping); inputRestrictions.clear(); std::vector<_Restriction>().swap(inputRestrictions); INFO("initializing contractor"); Contractor* contractor = new Contractor( n, edgeBasedEdgeList ); double contractionStartedTimestamp(get_timestamp()); contractor->Run(); INFO("Contraction took " << get_timestamp() - contractionStartedTimestamp << " sec"); std::vector< ContractionCleanup::Edge > contractedEdges; contractor->GetEdges( contractedEdges ); ContractionCleanup * cleanup = new ContractionCleanup(n, contractedEdges); contractedEdges.clear(); std::vector().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::_StrNode > _nodes; _nodes.resize( numberOfNodes); StaticGraph::EdgeIterator edge = 0; StaticGraph::EdgeIterator position = 0; for ( StaticGraph::NodeIterator node = 0; node <= numberOfNodes; ++node ) { StaticGraph::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*) &numberOfNodes, sizeof(unsigned)); edgeOutFile.write((char*) &_nodes[0], sizeof(StaticGraph::_StrNode)*(numberOfNodes)); //Serialize number of Edges edgeOutFile.write((char*) &position, sizeof(unsigned)); edge = 0; int counter = 0; StaticGraph::_StrEdge currentEdge; for ( StaticGraph::NodeIterator node = 0; node < numberOfNodes; ++node ) { for ( StaticGraph::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::_StrEdge)); ++edge; ++counter; } } INFO("Written " << counter << " edges, expected " << position); edgeOutFile.close(); cleanedEdgeList.clear(); _nodes.clear(); INFO("finished preprocessing"); return 0; }