233 lines
7.8 KiB
C++
233 lines
7.8 KiB
C++
/*
|
|
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
|
|
|
|
#define VERBOSE(x) x
|
|
#define VERBOSE2(x)
|
|
|
|
#ifdef NDEBUG
|
|
#undef VERBOSE
|
|
#undef VERBOSE2
|
|
#endif
|
|
|
|
#include <climits>
|
|
#include <fstream>
|
|
#include <istream>
|
|
#include <iostream>
|
|
#include <cstring>
|
|
#include <string>
|
|
#include <vector>
|
|
|
|
#ifdef _OPENMP
|
|
#include <omp.h>
|
|
#endif
|
|
|
|
#include "typedefs.h"
|
|
#include "Contractor/Contractor.h"
|
|
#include "Contractor/ContractionCleanup.h"
|
|
#include "DataStructures/BinaryHeap.h"
|
|
#include "DataStructures/LevelInformation.h"
|
|
#include "DataStructures/NNGrid.h"
|
|
#include "DataStructures/TurnInfoFactory.h"
|
|
#include "Util/BaseConfiguration.h"
|
|
#include "Util/InputFileUtil.h"
|
|
#include "Util/GraphLoader.h"
|
|
|
|
using namespace std;
|
|
|
|
typedef ContractionCleanup::Edge::EdgeData EdgeData;
|
|
typedef DynamicGraph<EdgeData>::InputEdge InputEdge;
|
|
typedef StaticGraph<EdgeData>::InputEdge StaticEdge;
|
|
typedef NNGrid::NNGrid<true> WritableGrid;
|
|
typedef BaseConfiguration ContractorConfiguration;
|
|
|
|
vector<NodeInfo> * int2ExtNodeMap = new vector<NodeInfo>();
|
|
|
|
int main (int argc, char *argv[]) {
|
|
if(argc <= 1) {
|
|
cerr << "usage: " << endl << argv[0] << " <osrm-data>" << endl;
|
|
exit(-1);
|
|
}
|
|
|
|
//todo: check if contractor exists
|
|
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 = readOSRMGraphFromStream(in, edgeList, int2ExtNodeMap);
|
|
in.close();
|
|
|
|
cout << "computing turn vector info ..." << flush;
|
|
TurnInfoFactory * infoFactory = new TurnInfoFactory(n, edgeList);
|
|
infoFactory->Run();
|
|
delete infoFactory;
|
|
cout << "ok" << endl;
|
|
|
|
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");
|
|
ofstream mapOutFile(nodeOut, ios::binary);
|
|
|
|
WritableGrid * g = new WritableGrid();
|
|
cout << "building grid ..." << flush;
|
|
Percent p(edgeList.size());
|
|
for(NodeID i = 0; i < edgeList.size(); i++) {
|
|
p.printIncrement();
|
|
if(!edgeList[i].isLocatable())
|
|
continue;
|
|
int slat = int2ExtNodeMap->at(edgeList[i].source()).lat;
|
|
int slon = int2ExtNodeMap->at(edgeList[i].source()).lon;
|
|
int tlat = int2ExtNodeMap->at(edgeList[i].target()).lat;
|
|
int tlon = int2ExtNodeMap->at(edgeList[i].target()).lon;
|
|
g->AddEdge(
|
|
_Edge(
|
|
edgeList[i].source(),
|
|
edgeList[i].target(),
|
|
0,
|
|
((edgeList[i].isBackward() && edgeList[i].isForward()) ? 0 : 1),
|
|
edgeList[i].weight()
|
|
),
|
|
|
|
_Coordinate(slat, slon),
|
|
_Coordinate(tlat, tlon)
|
|
);
|
|
}
|
|
g->ConstructGrid(ramIndexOut, fileIndexOut);
|
|
delete g;
|
|
|
|
unsigned numberOfNodes = int2ExtNodeMap->size();
|
|
//Serializing the node map.
|
|
for(NodeID i = 0; i < int2ExtNodeMap->size(); i++) {
|
|
mapOutFile.write((char *)&(int2ExtNodeMap->at(i)), sizeof(NodeInfo));
|
|
}
|
|
mapOutFile.close();
|
|
int2ExtNodeMap->clear();
|
|
delete int2ExtNodeMap;
|
|
|
|
cout << "initializing contractor ..." << flush;
|
|
Contractor* contractor = new Contractor( n, edgeList );
|
|
|
|
contractor->Run();
|
|
|
|
cout << "checking data sanity ..." << flush;
|
|
contractor->CheckForAllOrigEdges(edgeList);
|
|
cout << "ok" << endl;
|
|
LevelInformation * levelInfo = contractor->GetLevelInformation();
|
|
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];
|
|
assert(node < numberOfNodes);
|
|
levelOutFile.write((char *)&node, sizeof(unsigned));
|
|
}
|
|
}
|
|
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;
|
|
|
|
ofstream edgeOutFile(edgeOut, ios::binary);
|
|
|
|
//Serializing the edge list.
|
|
cout << "Serializing edges " << flush;
|
|
p.reinit(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;
|
|
|
|
bool forwardTurn = it->data.forwardTurn;
|
|
bool backwardTurn = it->data.backwardTurn;
|
|
|
|
edgeOutFile.write((char *)&(distance), sizeof(int));
|
|
edgeOutFile.write((char *)&(forwardTurn), sizeof(bool));
|
|
edgeOutFile.write((char *)&(backwardTurn), sizeof(bool));
|
|
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();
|
|
|
|
cout << "finished" << endl;
|
|
}
|