BREAKING CHANGE: the routing engine does not use the kd-tree anymore, but an external memory nearest neighbor grid. The memory consumption is less than half. This is a breaking change, please reprocess your .osrm files and take note that the parameter to routed have been changed!
Known Bug: There are some minor rounding errors that affect the position of start and destination node by a few feet.
This commit is contained in:
parent
027c0e46ee
commit
0875c2d557
@ -58,7 +58,6 @@ private:
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
public:
|
||||
|
||||
struct Edge {
|
||||
|
@ -293,8 +293,7 @@ public:
|
||||
for ( int threadNum = 0; threadNum < maxThreads; ++threadNum ) {
|
||||
threadData.push_back( new _ThreadData( numberOfNodes ) );
|
||||
}
|
||||
cout << numberOfNodes << " nodes, " << _graph->GetNumberOfEdges() << " edges" << endl;
|
||||
cout << "using " << maxThreads << " threads" << endl;
|
||||
cout << "Contractor is using " << maxThreads << " threads" << endl;
|
||||
|
||||
NodeID levelID = 0;
|
||||
NodeID iteration = 0;
|
||||
@ -520,7 +519,6 @@ private:
|
||||
delete bfsStack;
|
||||
}
|
||||
|
||||
|
||||
double _Timestamp() {
|
||||
return time(NULL);
|
||||
}
|
||||
|
@ -16,7 +16,7 @@ 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.
|
||||
*/
|
||||
*/
|
||||
|
||||
#ifndef SEARCHENGINE_H_
|
||||
#define SEARCHENGINE_H_
|
||||
@ -25,6 +25,7 @@ or see http://www.gnu.org/licenses/agpl.txt.
|
||||
#include <deque>
|
||||
|
||||
#include "BinaryHeap.h"
|
||||
#include "../DataStructures/PhantomNodes.h"
|
||||
#include "../typedefs.h"
|
||||
|
||||
struct _HeapData {
|
||||
@ -34,17 +35,19 @@ struct _HeapData {
|
||||
|
||||
typedef BinaryHeap< NodeID, int, int, _HeapData, DenseStorage< NodeID, unsigned > > _Heap;
|
||||
|
||||
template<typename EdgeData, typename GraphT, typename KDTST = NodeInformationHelpDesk>
|
||||
template<typename EdgeData, typename GraphT, typename NodeHelperT = NodeInformationHelpDesk>
|
||||
class SearchEngine {
|
||||
private:
|
||||
const GraphT * _graph;
|
||||
inline double absDouble(double input) { if(input < 0) return input*(-1); else return input;}
|
||||
public:
|
||||
SearchEngine(GraphT * g, KDTST * k) : _graph(g), nodeHelpDesk(k) {}
|
||||
SearchEngine(GraphT * g, NodeHelperT * nh) : _graph(g), nodeHelpDesk(nh) {}
|
||||
~SearchEngine() {}
|
||||
|
||||
const void getNodeInfo(NodeID id, NodeInfo * info) const
|
||||
const void getNodeInfo(NodeID id, _Coordinate& result) const
|
||||
{
|
||||
nodeHelpDesk->getExternalNodeInfo(id, info);
|
||||
result.lat = nodeHelpDesk->getLatitudeOfNode(id);
|
||||
result.lon = nodeHelpDesk->getLongitudeOfNode(id);
|
||||
}
|
||||
|
||||
unsigned int numberOfNodes() const
|
||||
@ -52,14 +55,77 @@ public:
|
||||
return nodeHelpDesk->getNumberOfNodes();
|
||||
}
|
||||
|
||||
unsigned int ComputeRoute(NodeID start, NodeID target, vector<NodeID> * path)
|
||||
unsigned int ComputeRoute(PhantomNodes * phantomNodes, vector<NodeID> * path, _Coordinate& startCoord, _Coordinate& targetCoord)
|
||||
{
|
||||
bool onSameEdge = false;
|
||||
_Heap * _forwardHeap = new _Heap(nodeHelpDesk->getNumberOfNodes());
|
||||
_Heap * _backwardHeap = new _Heap(nodeHelpDesk->getNumberOfNodes());
|
||||
NodeID middle = ( NodeID ) 0;
|
||||
unsigned int _upperbound = std::numeric_limits<unsigned int>::max();
|
||||
_forwardHeap->Insert(start, 0, start);
|
||||
_backwardHeap->Insert(target, 0, target);
|
||||
|
||||
if(phantomNodes->startNode1 == UINT_MAX || phantomNodes->startNode2 == UINT_MAX)
|
||||
return _upperbound;
|
||||
|
||||
if( (phantomNodes->startNode1 == phantomNodes->targetNode1 && phantomNodes->startNode2 == phantomNodes->targetNode2 ) )
|
||||
{
|
||||
EdgeID currentEdge = _graph->FindEdge( phantomNodes->startNode1, phantomNodes->startNode2 );
|
||||
if(currentEdge == UINT_MAX)
|
||||
currentEdge = _graph->FindEdge( phantomNodes->startNode2, phantomNodes->startNode1 );
|
||||
if(currentEdge != UINT_MAX && _graph->GetEdgeData(currentEdge).forward && phantomNodes->startRatio < phantomNodes->targetRatio)
|
||||
{ //upperbound auf kantenlänge setzen
|
||||
cout << "start and target on same edge" << endl;
|
||||
onSameEdge = true;
|
||||
_upperbound = 10 * ApproximateDistance(phantomNodes->startCoord.lat, phantomNodes->startCoord.lon, phantomNodes->targetCoord.lat, phantomNodes->targetCoord.lon);
|
||||
} else if (currentEdge != UINT_MAX && !_graph->GetEdgeData(currentEdge).backward) {
|
||||
EdgeWeight w = _graph->GetEdgeData( currentEdge ).distance;
|
||||
_forwardHeap->Insert(phantomNodes->startNode2, absDouble(w*phantomNodes->startRatio), phantomNodes->startNode2);
|
||||
_backwardHeap->Insert(phantomNodes->startNode1, absDouble(w-w*phantomNodes->startRatio), phantomNodes->startNode1);
|
||||
} else if (currentEdge != UINT_MAX && _graph->GetEdgeData(currentEdge).backward)
|
||||
{
|
||||
onSameEdge = true;
|
||||
_upperbound = 10 * ApproximateDistance(phantomNodes->startCoord.lat, phantomNodes->startCoord.lon, phantomNodes->targetCoord.lat, phantomNodes->targetCoord.lon);
|
||||
}
|
||||
} else {
|
||||
if(phantomNodes->startNode1 != UINT_MAX)
|
||||
{
|
||||
EdgeID forwardEdge = _graph->FindEdge( phantomNodes->startNode1, phantomNodes->startNode2);
|
||||
if(forwardEdge == UINT_MAX)
|
||||
forwardEdge = _graph->FindEdge( phantomNodes->startNode2, phantomNodes->startNode1 );
|
||||
if(forwardEdge != UINT_MAX && _graph->GetEdgeData(forwardEdge).forward )
|
||||
{ //insert forward edge (coord, s1) in forward heap;
|
||||
EdgeWeight w = _graph->GetEdgeData(forwardEdge ).distance;
|
||||
_forwardHeap->Insert(phantomNodes->startNode1, absDouble(w*phantomNodes->startRatio), phantomNodes->startNode1);
|
||||
}
|
||||
EdgeID backEdge = _graph->FindEdge( phantomNodes->startNode2, phantomNodes->startNode1);
|
||||
if(backEdge == UINT_MAX)
|
||||
backEdge = _graph->FindEdge( phantomNodes->startNode1, phantomNodes->startNode2 );
|
||||
if(backEdge != UINT_MAX && _graph->GetEdgeData(backEdge).backward )
|
||||
{ //insert forward edge (coord, s2) in forward heap;
|
||||
EdgeWeight w = _graph->GetEdgeData( backEdge ).distance;
|
||||
_forwardHeap->Insert(phantomNodes->startNode2, absDouble(w-w*phantomNodes->startRatio), phantomNodes->startNode2);
|
||||
}
|
||||
}
|
||||
if(phantomNodes->targetNode1 != UINT_MAX)
|
||||
{
|
||||
EdgeID forwardEdge = _graph->FindEdge( phantomNodes->targetNode1, phantomNodes->targetNode2);
|
||||
if(forwardEdge == UINT_MAX)
|
||||
forwardEdge = _graph->FindEdge( phantomNodes->targetNode2, phantomNodes->targetNode1 );
|
||||
|
||||
if(forwardEdge != UINT_MAX && _graph->GetEdgeData(forwardEdge).forward )
|
||||
{ //insert forward edge (coord, s1) in forward heap;
|
||||
EdgeWeight w = _graph->GetEdgeData( forwardEdge ).distance;
|
||||
_backwardHeap->Insert(phantomNodes->targetNode1, absDouble(w * phantomNodes->targetRatio), phantomNodes->targetNode1);
|
||||
}
|
||||
EdgeID backwardEdge = _graph->FindEdge( phantomNodes->targetNode2, phantomNodes->targetNode1);
|
||||
if(backwardEdge == UINT_MAX)
|
||||
backwardEdge = _graph->FindEdge( phantomNodes->targetNode1, phantomNodes->targetNode2 );
|
||||
if(backwardEdge != UINT_MAX && _graph->GetEdgeData( backwardEdge ).backward )
|
||||
{ //insert forward edge (coord, s2) in forward heap;
|
||||
EdgeWeight w = _graph->GetEdgeData( backwardEdge ).distance;
|
||||
_backwardHeap->Insert(phantomNodes->targetNode2, absDouble(w - w * phantomNodes->targetRatio), phantomNodes->targetNode2);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
while(_forwardHeap->Size() + _backwardHeap->Size() > 0)
|
||||
{
|
||||
@ -71,24 +137,21 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
if ( _upperbound == std::numeric_limits< unsigned int >::max() )
|
||||
if ( _upperbound == std::numeric_limits< unsigned int >::max() || onSameEdge )
|
||||
return _upperbound;
|
||||
|
||||
NodeID pathNode = middle;
|
||||
NodeID unpackEndNode = start;
|
||||
deque< NodeID > packedPath;
|
||||
|
||||
while ( pathNode != unpackEndNode ) {
|
||||
while ( pathNode != phantomNodes->startNode1 && pathNode != phantomNodes->startNode2 ) {
|
||||
pathNode = _forwardHeap->GetData( pathNode ).parent;
|
||||
packedPath.push_front( pathNode );
|
||||
}
|
||||
|
||||
packedPath.push_back( middle );
|
||||
|
||||
pathNode = middle;
|
||||
unpackEndNode = target;
|
||||
|
||||
while ( pathNode != unpackEndNode ) {
|
||||
while ( pathNode != phantomNodes->targetNode2 && pathNode != phantomNodes->targetNode1 ) {
|
||||
pathNode = _backwardHeap->GetData( pathNode ).parent;
|
||||
packedPath.push_back( pathNode );
|
||||
}
|
||||
@ -107,12 +170,17 @@ public:
|
||||
return _upperbound/10;
|
||||
}
|
||||
|
||||
unsigned int findNearestNodeForLatLon(const int lat, const int lon, NodeCoords<NodeID> * data) const
|
||||
inline unsigned int findNearestNodeForLatLon(const _Coordinate& coord, _Coordinate& result) const
|
||||
{
|
||||
return nodeHelpDesk->findNearestNodeIDForLatLon( lat, lon, data);
|
||||
nodeHelpDesk->findNearestNodeIDForLatLon( coord, result );
|
||||
}
|
||||
|
||||
inline bool FindRoutingStarts(const _Coordinate start, const _Coordinate target, PhantomNodes * routingStarts)
|
||||
{
|
||||
nodeHelpDesk->FindRoutingStarts(start, target, routingStarts);
|
||||
}
|
||||
private:
|
||||
KDTST * nodeHelpDesk;
|
||||
NodeHelperT * nodeHelpDesk;
|
||||
|
||||
void _RoutingStep(_Heap * _forwardHeap, _Heap *_backwardHeap, const bool& forwardDirection, NodeID * middle, unsigned int * _upperbound)
|
||||
{
|
||||
@ -160,7 +228,6 @@ private:
|
||||
EdgeWeight smallestWeight = UINT_MAX;
|
||||
for(typename GraphT::EdgeIterator eit = _graph->BeginEdges(source); eit < _graph->EndEdges(source); eit++)
|
||||
{
|
||||
//const NodeID target = GetTarget(edge);
|
||||
const EdgeWeight weight = _graph->GetEdgeData(eit).distance;
|
||||
{
|
||||
if(_graph->GetTarget(eit) == target && weight < smallestWeight && _graph->GetEdgeData(eit).forward)
|
||||
@ -173,7 +240,6 @@ private:
|
||||
{
|
||||
for(typename GraphT::EdgeIterator eit = _graph->BeginEdges(target); eit < _graph->EndEdges(target); eit++)
|
||||
{
|
||||
//const NodeID target = GetTarget(edge);
|
||||
const EdgeWeight weight = _graph->GetEdgeData(eit).distance;
|
||||
{
|
||||
if(_graph->GetTarget(eit) == source && weight < smallestWeight && _graph->GetEdgeData(eit).backward)
|
||||
|
@ -23,6 +23,8 @@ or see http://www.gnu.org/licenses/agpl.txt.
|
||||
|
||||
#include <climits>
|
||||
#include <cmath>
|
||||
#include <string>
|
||||
#include <libxml/xmlreader.h>
|
||||
|
||||
/* Default Speed Profile:
|
||||
motorway 110
|
||||
@ -41,7 +43,7 @@ or see http://www.gnu.org/licenses/agpl.txt.
|
||||
ferry 25
|
||||
*/
|
||||
|
||||
string names[14] = { "motorway", "motorway_link", "trunk", "trunk_link", "primary", "primary_link", "secondary", "secondary_link", "tertiary", "unclassified", "residential", "living_street", "service", "ferry" };
|
||||
std::string names[14] = { "motorway", "motorway_link", "trunk", "trunk_link", "primary", "primary_link", "secondary", "secondary_link", "tertiary", "unclassified", "residential", "living_street", "service", "ferry" };
|
||||
double speeds[14] = { 110, 90, 90, 70, 70, 60, 60, 50, 55, 50, 40 , 10, 30, 25};
|
||||
|
||||
struct _Node : NodeInfo{
|
||||
@ -67,7 +69,8 @@ struct _Node : NodeInfo{
|
||||
struct _Coordinate {
|
||||
int lat;
|
||||
int lon;
|
||||
_Coordinate () : lat(INT_MIN), lon(INT_MIN) {};
|
||||
_Coordinate () : lat(INT_MIN), lon(INT_MIN) {}
|
||||
_Coordinate (int t, int n) : lat(t) , lon(n) {}
|
||||
};
|
||||
|
||||
struct _Way {
|
||||
@ -90,6 +93,7 @@ struct _Relation {
|
||||
struct _Edge {
|
||||
_Edge() {};
|
||||
_Edge(NodeID s, NodeID t) : start(s), target(t) { }
|
||||
_Edge(NodeID s, NodeID t, short tp, short d, double sp): start(s), target(t), type(tp), direction(d), speed(sp) { }
|
||||
NodeID start;
|
||||
NodeID target;
|
||||
short type;
|
||||
@ -348,12 +352,12 @@ _Node _ReadXMLNode( xmlTextReaderPtr& inputReader ) {
|
||||
|
||||
xmlChar* attribute = xmlTextReaderGetAttribute( inputReader, ( const xmlChar* ) "lat" );
|
||||
if ( attribute != NULL ) {
|
||||
node.lat = static_cast<NodeID>(100000*atof(( const char* ) attribute ) );
|
||||
node.lat = static_cast<NodeID>(100000.*atof(( const char* ) attribute ) );
|
||||
xmlFree( attribute );
|
||||
}
|
||||
attribute = xmlTextReaderGetAttribute( inputReader, ( const xmlChar* ) "lon" );
|
||||
if ( attribute != NULL ) {
|
||||
node.lon = static_cast<NodeID>(100000*atof(( const char* ) attribute ));
|
||||
node.lon = static_cast<NodeID>(100000.*atof(( const char* ) attribute ));
|
||||
xmlFree( attribute );
|
||||
}
|
||||
attribute = xmlTextReaderGetAttribute( inputReader, ( const xmlChar* ) "id" );
|
71
DataStructures/GridEdge.h
Normal file
71
DataStructures/GridEdge.h
Normal file
@ -0,0 +1,71 @@
|
||||
/*
|
||||
open source routing machine
|
||||
Copyright (C) Dennis Luxen, others 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.
|
||||
*/
|
||||
|
||||
#ifndef GRIDEDGE_H_
|
||||
#define GRIDEDGE_H_
|
||||
|
||||
struct GridEdgeData {
|
||||
GridEdgeData(_Edge e, unsigned f, unsigned r) : edge(e), fileIndex(f), ramIndex(r) {}
|
||||
GridEdgeData() {}
|
||||
_Edge edge;
|
||||
unsigned ramIndex;
|
||||
unsigned fileIndex;
|
||||
bool operator< ( const GridEdgeData& right ) const {
|
||||
if(right.edge.start != edge.start)
|
||||
return right.edge.start < edge.start;
|
||||
if(right.edge.target != edge.target)
|
||||
return right.edge.target < edge.target;
|
||||
}
|
||||
bool operator==( const GridEdgeData& right ) const {
|
||||
return right.edge.start == edge.start && right.edge.target == edge.target;
|
||||
}
|
||||
};
|
||||
|
||||
struct CompareGridEdgeDataByFileIndex
|
||||
{
|
||||
bool operator () (const GridEdgeData & a, const GridEdgeData & b) const
|
||||
{
|
||||
return a.fileIndex < b.fileIndex;
|
||||
}
|
||||
};
|
||||
|
||||
struct CompareGridEdgeDataByRamIndex
|
||||
{
|
||||
typedef GridEdgeData value_type;
|
||||
|
||||
bool operator () (const GridEdgeData & a, const GridEdgeData & b) const
|
||||
{
|
||||
return a.ramIndex < b.ramIndex;
|
||||
}
|
||||
value_type max_value()
|
||||
{
|
||||
GridEdgeData e;
|
||||
e.ramIndex = (1024*1024) - 1;
|
||||
return e;
|
||||
}
|
||||
value_type min_value()
|
||||
{
|
||||
GridEdgeData e;
|
||||
e.ramIndex = 0;
|
||||
return e;
|
||||
}
|
||||
};
|
||||
|
||||
#endif /* GRIDEDGE_H_ */
|
@ -66,7 +66,6 @@ int readFromBz2Stream( void* pointer, char* buffer, int len )
|
||||
int closeBz2Stream( void *pointer )
|
||||
{
|
||||
BZ2Context* context = (BZ2Context*) pointer;
|
||||
BZ2_bzclose( context->bz2 );
|
||||
fclose( context->file );
|
||||
delete context;
|
||||
return 0;
|
||||
|
595
DataStructures/NNGrid.h
Normal file
595
DataStructures/NNGrid.h
Normal file
@ -0,0 +1,595 @@
|
||||
/*
|
||||
open source routing machine
|
||||
Copyright (C) Dennis Luxen, others 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.
|
||||
*/
|
||||
|
||||
#ifndef NNGRID_H_
|
||||
#define NNGRID_H_
|
||||
|
||||
#include <fstream>
|
||||
|
||||
#include <cassert>
|
||||
#include <limits>
|
||||
#include <cmath>
|
||||
#include <vector>
|
||||
#include <stxxl.h>
|
||||
#include <google/dense_hash_map>
|
||||
|
||||
#include "ExtractorStructs.h"
|
||||
#include "GridEdge.h"
|
||||
#include "Percent.h"
|
||||
#include "PhantomNodes.h"
|
||||
#include "Util.h"
|
||||
|
||||
#include "StaticGraph.h"
|
||||
|
||||
namespace NNGrid{
|
||||
static unsigned getFileIndexForLatLon(const int lt, const int ln)
|
||||
{
|
||||
double lat = lt/100000.;
|
||||
double lon = ln/100000.;
|
||||
|
||||
double x = ( lon + 180.0 ) / 360.0;
|
||||
double y = ( lat + 90.0 ) / 180.0;
|
||||
|
||||
assert( x<=1.0 && x >= 0);
|
||||
assert( y<=1.0 && y >= 0);
|
||||
|
||||
unsigned line = 1073741824.0*y;
|
||||
line = line - (line % 32768);
|
||||
assert(line % 32768 == 0);
|
||||
unsigned column = 32768.*x;
|
||||
unsigned fileIndex = line+column;
|
||||
return fileIndex;
|
||||
}
|
||||
|
||||
static unsigned getRAMIndexFromFileIndex(const int fileIndex)
|
||||
{
|
||||
unsigned fileLine = fileIndex / 32768;
|
||||
fileLine = fileLine / 32;
|
||||
fileLine = fileLine * 1024;
|
||||
unsigned fileColumn = (fileIndex % 32768);
|
||||
fileColumn = fileColumn / 32;
|
||||
unsigned ramIndex = fileLine + fileColumn;
|
||||
assert(ramIndex < 1024*1024);
|
||||
return ramIndex;
|
||||
}
|
||||
|
||||
static inline int signum(int x){
|
||||
return (x > 0) ? 1 : (x < 0) ? -1 : 0;
|
||||
}
|
||||
|
||||
static void bresenham(int xstart,int ystart,int xend,int yend, std::vector<std::pair<unsigned, unsigned> > &indexList)
|
||||
{
|
||||
int x, y, t, dx, dy, incx, incy, pdx, pdy, ddx, ddy, es, el, err;
|
||||
|
||||
dx = xend - xstart;
|
||||
dy = yend - ystart;
|
||||
|
||||
incx = signum(dx);
|
||||
incy = signum(dy);
|
||||
if(dx<0) dx = -dx;
|
||||
if(dy<0) dy = -dy;
|
||||
|
||||
if (dx>dy)
|
||||
{
|
||||
pdx=incx; pdy=0;
|
||||
ddx=incx; ddy=incy;
|
||||
es =dy; el =dx;
|
||||
} else
|
||||
{
|
||||
pdx=0; pdy=incy;
|
||||
ddx=incx; ddy=incy;
|
||||
es =dx; el =dy;
|
||||
}
|
||||
x = xstart;
|
||||
y = ystart;
|
||||
err = el/2;
|
||||
{
|
||||
int fileIndex = (y-1)*32768 + x;
|
||||
int ramIndex = getRAMIndexFromFileIndex(fileIndex);
|
||||
indexList.push_back(std::make_pair(fileIndex, ramIndex));
|
||||
}
|
||||
|
||||
for(t=0; t<el; ++t)
|
||||
{
|
||||
err -= es;
|
||||
if(err<0)
|
||||
{
|
||||
err += el;
|
||||
x += ddx;
|
||||
y += ddy;
|
||||
} else
|
||||
{
|
||||
x += pdx;
|
||||
y += pdy;
|
||||
}
|
||||
{
|
||||
int fileIndex = (y-1)*32768 + x;
|
||||
int ramIndex = getRAMIndexFromFileIndex(fileIndex);
|
||||
indexList.push_back(std::make_pair(fileIndex, ramIndex));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void getListOfIndexesForEdgeAndGridSize(_Coordinate& start, _Coordinate& target, std::vector<std::pair<unsigned, unsigned> > &indexList)
|
||||
{
|
||||
double lat1 = start.lat/100000.;
|
||||
double lon1 = start.lon/100000.;
|
||||
|
||||
double x1 = ( lon1 + 180.0 ) / 360.0;
|
||||
double y1 = ( lat1 + 90.0 ) / 180.0;
|
||||
|
||||
double lat2 = target.lat/100000.;
|
||||
double lon2 = target.lon/100000.;
|
||||
|
||||
double x2 = ( lon2 + 180.0 ) / 360.0;
|
||||
double y2 = ( lat2 + 90.0 ) / 180.0;
|
||||
|
||||
bresenham(x1*32768, y1*32768, x2*32768, y2*32768, indexList);
|
||||
}
|
||||
|
||||
class NNGrid {
|
||||
|
||||
public:
|
||||
NNGrid() { ramIndexTable.resize((1024*1024), UINT_MAX); }
|
||||
|
||||
NNGrid(const char* rif, const char* iif) {
|
||||
ramIndexTable.resize((1024*1024), UINT_MAX);
|
||||
indexInFile.open(iif, std::ios::in | std::ios::binary);
|
||||
ramInFile.open(rif, std::ios::in | std::ios::binary);
|
||||
}
|
||||
|
||||
~NNGrid() {
|
||||
if(ramInFile.is_open()) ramInFile.close();
|
||||
if(indexInFile.is_open()) indexInFile.close();
|
||||
}
|
||||
|
||||
void OpenIndexFiles()
|
||||
{
|
||||
assert(ramInFile.is_open());
|
||||
assert(indexInFile.is_open());
|
||||
|
||||
for(int i = 0; i < 1024*1024; i++)
|
||||
{
|
||||
unsigned temp;
|
||||
ramInFile.read((char*)&temp, sizeof(unsigned));
|
||||
ramIndexTable[i] = temp;
|
||||
}
|
||||
ramInFile.close();
|
||||
}
|
||||
|
||||
void AddEdge(_Edge edge, _Coordinate start, _Coordinate target)
|
||||
{
|
||||
edge.startCoord = start;
|
||||
edge.targetCoord = target;
|
||||
|
||||
std::vector<std::pair<unsigned, unsigned> > indexList;
|
||||
getListOfIndexesForEdgeAndGridSize(start, target, indexList);
|
||||
for(int i = 0; i < indexList.size(); i++)
|
||||
{
|
||||
entries.push_back(GridEdgeData(edge, indexList[i].first, indexList[i].second));
|
||||
}
|
||||
}
|
||||
|
||||
void ConstructGrid(char * ramIndexOut, char * fileIndexOut)
|
||||
{
|
||||
double timestamp = get_timestamp();
|
||||
//create index file on disk, old one is over written
|
||||
indexOutFile.open(fileIndexOut, std::ios::out | std::ios::binary | std::ios::trunc);
|
||||
cout << "sorting grid data consisting of " << entries.size() << " edges..." << flush;
|
||||
//sort entries
|
||||
stxxl::sort(entries.begin(), entries.end(), CompareGridEdgeDataByRamIndex(), 1024*1024*1024);
|
||||
cout << "ok in " << (get_timestamp() - timestamp) << "s" << endl;
|
||||
std::vector<GridEdgeData> entriesInFileWithRAMSameIndex;
|
||||
unsigned indexInRamTable = entries.begin()->ramIndex;
|
||||
unsigned lastPositionInIndexFile = 0;
|
||||
unsigned numberOfUsedCells = 0;
|
||||
unsigned maxNumberOfRAMCellElements = 0;
|
||||
cout << "writing data ..." << flush;
|
||||
Percent p(entries.size());
|
||||
for(stxxl::vector<GridEdgeData>::iterator vt = entries.begin(); vt != entries.end(); vt++)
|
||||
{
|
||||
p.printIncrement();
|
||||
if(vt->ramIndex != indexInRamTable)
|
||||
{
|
||||
unsigned numberOfBytesInCell = FillCell(entriesInFileWithRAMSameIndex, lastPositionInIndexFile);
|
||||
if(entriesInFileWithRAMSameIndex.size() > maxNumberOfRAMCellElements)
|
||||
maxNumberOfRAMCellElements = entriesInFileWithRAMSameIndex.size();
|
||||
|
||||
ramIndexTable[indexInRamTable] = lastPositionInIndexFile;
|
||||
lastPositionInIndexFile += numberOfBytesInCell;
|
||||
entriesInFileWithRAMSameIndex.clear();
|
||||
indexInRamTable = vt->ramIndex;
|
||||
numberOfUsedCells++;
|
||||
}
|
||||
entriesInFileWithRAMSameIndex.push_back(*vt);
|
||||
}
|
||||
unsigned numberOfBytesInCell = FillCell(entriesInFileWithRAMSameIndex, lastPositionInIndexFile);
|
||||
ramIndexTable[indexInRamTable] = lastPositionInIndexFile;
|
||||
numberOfUsedCells++;
|
||||
entriesInFileWithRAMSameIndex.clear();
|
||||
|
||||
assert(entriesInFileWithRAMSameIndex.size() == 0);
|
||||
|
||||
for(int i = 0; i < 1024*1024; i++)
|
||||
{
|
||||
if(ramIndexTable[i] != UINT_MAX){
|
||||
numberOfUsedCells--;
|
||||
}
|
||||
}
|
||||
assert(numberOfUsedCells == 0);
|
||||
|
||||
//close index file
|
||||
indexOutFile.close();
|
||||
//Serialize RAM Index
|
||||
ofstream ramFile(ramIndexOut, std::ios::out | std::ios::binary | std::ios::trunc);
|
||||
//write 4 MB of index Table in RAM
|
||||
for(int i = 0; i < 1024*1024; i++)
|
||||
ramFile.write((char *)&ramIndexTable[i], sizeof(unsigned) );
|
||||
//close ram index file
|
||||
ramFile.close();
|
||||
}
|
||||
|
||||
bool FindRoutingStarts(const _Coordinate startCoord, const _Coordinate targetCoord, PhantomNodes * routingStarts) {
|
||||
|
||||
unsigned fileIndex = getFileIndexForLatLon(startCoord.lat, startCoord.lon);
|
||||
std::vector<_Edge> candidates;
|
||||
double timestamp = get_timestamp();
|
||||
for(int j = -32768; j < (32768+1); j+=32768){
|
||||
for(int i = -1; i < 2; i++){
|
||||
GetContentsOfFileBucket(fileIndex+i+j, candidates);
|
||||
}
|
||||
}
|
||||
|
||||
_Coordinate tmp;
|
||||
double dist = numeric_limits<double>::max();
|
||||
timestamp = get_timestamp();
|
||||
for(std::vector<_Edge>::iterator it = candidates.begin(); it != candidates.end(); it++)
|
||||
{
|
||||
double r = 0.;
|
||||
double tmpDist = ComputeDistance(startCoord, it->startCoord, it->targetCoord, tmp, &r);
|
||||
if(tmpDist < dist)
|
||||
{
|
||||
routingStarts->startNode1 = it->start;
|
||||
routingStarts->startNode2 = it->target;
|
||||
routingStarts->startRatio = r;
|
||||
dist = tmpDist;
|
||||
routingStarts->startCoord.lat = tmp.lat;
|
||||
routingStarts->startCoord.lon = tmp.lon;
|
||||
}
|
||||
}
|
||||
|
||||
fileIndex = getFileIndexForLatLon(targetCoord.lat, targetCoord.lon);
|
||||
candidates.clear();
|
||||
timestamp = get_timestamp();
|
||||
for(int j = -32768; j < (32768+1); j+=32768){
|
||||
for(int i = -1; i < 2; i++){
|
||||
GetContentsOfFileBucket(fileIndex+i+j, candidates);
|
||||
}
|
||||
}
|
||||
|
||||
dist = numeric_limits<double>::max();
|
||||
timestamp = get_timestamp();
|
||||
for(std::vector<_Edge>::iterator it = candidates.begin(); it != candidates.end(); it++)
|
||||
{
|
||||
double r = 0.;
|
||||
double tmpDist = ComputeDistance(targetCoord, it->startCoord, it->targetCoord, tmp, &r);
|
||||
if(tmpDist < dist)
|
||||
{
|
||||
routingStarts->targetNode1 = it->start;
|
||||
routingStarts->targetNode2 = it->target;
|
||||
routingStarts->targetRatio = r;
|
||||
dist = tmpDist;
|
||||
routingStarts->targetCoord.lat = tmp.lat;
|
||||
routingStarts->targetCoord.lon = tmp.lon;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
_Coordinate FindNearestPointOnEdge(const _Coordinate& inputCoordinate)
|
||||
{
|
||||
unsigned fileIndex = getFileIndexForLatLon(inputCoordinate.lat, inputCoordinate.lon);
|
||||
std::vector<_Edge> candidates;
|
||||
double timestamp = get_timestamp();
|
||||
for(int j = -32768; j < (32768+1); j+=32768){
|
||||
for(int i = -1; i < 2; i++){
|
||||
GetContentsOfFileBucket(fileIndex+i+j, candidates);
|
||||
}
|
||||
}
|
||||
|
||||
_Coordinate nearest, tmp;
|
||||
double dist = numeric_limits<double>::max();
|
||||
timestamp = get_timestamp();
|
||||
for(std::vector<_Edge>::iterator it = candidates.begin(); it != candidates.end(); it++)
|
||||
{
|
||||
double r = 0.;
|
||||
double tmpDist = ComputeDistance(inputCoordinate, it->startCoord, it->targetCoord, tmp, &r);
|
||||
if(tmpDist < dist)
|
||||
{
|
||||
dist = tmpDist;
|
||||
nearest = tmp;
|
||||
}
|
||||
}
|
||||
return nearest;
|
||||
}
|
||||
|
||||
private:
|
||||
unsigned FillCell(std::vector<GridEdgeData>& entriesWithSameRAMIndex, unsigned fileOffset )
|
||||
{
|
||||
vector<char> tmpBuffer;
|
||||
tmpBuffer.resize(32*32*4096,0);
|
||||
unsigned indexIntoTmpBuffer = 0;
|
||||
unsigned numberOfWrittenBytes = 0;
|
||||
assert(indexOutFile.is_open());
|
||||
|
||||
vector<unsigned> cellIndex;
|
||||
cellIndex.resize(32*32,UINT_MAX);
|
||||
google::dense_hash_map< unsigned, unsigned > * cellMap = new google::dense_hash_map< unsigned, unsigned >(1024);
|
||||
cellMap->set_empty_key(UINT_MAX);
|
||||
|
||||
unsigned ramIndex = entriesWithSameRAMIndex.begin()->ramIndex;
|
||||
unsigned lineBase = ramIndex/1024;
|
||||
lineBase = lineBase*32*32768;
|
||||
unsigned columnBase = ramIndex%1024;
|
||||
columnBase=columnBase*32;
|
||||
|
||||
for(int i = 0; i < 32; i++)
|
||||
{
|
||||
for(int j = 0; j < 32; j++)
|
||||
{
|
||||
unsigned fileIndex = lineBase + i*32768 + columnBase+j;
|
||||
unsigned cellIndex = i*32+j;
|
||||
cellMap->insert(std::make_pair(fileIndex, cellIndex));
|
||||
}
|
||||
}
|
||||
|
||||
for(int i = 0; i < entriesWithSameRAMIndex.size() -1; i++)
|
||||
{
|
||||
assert(entriesWithSameRAMIndex[i].ramIndex== entriesWithSameRAMIndex[i+1].ramIndex);
|
||||
}
|
||||
|
||||
//sort & unique
|
||||
std::sort(entriesWithSameRAMIndex.begin(), entriesWithSameRAMIndex.end(), CompareGridEdgeDataByFileIndex());
|
||||
std::vector<GridEdgeData>::iterator uniqueEnd = std::unique(entriesWithSameRAMIndex.begin(), entriesWithSameRAMIndex.end());
|
||||
|
||||
//traverse each file bucket and write its contents to disk
|
||||
std::vector<GridEdgeData> entriesWithSameFileIndex;
|
||||
unsigned fileIndex = entriesWithSameRAMIndex.begin()->fileIndex;
|
||||
|
||||
for(std::vector<GridEdgeData>::iterator it = entriesWithSameRAMIndex.begin(); it != uniqueEnd; it++)
|
||||
{
|
||||
assert(cellMap->find(it->fileIndex) != cellMap->end() ); //asserting that file index belongs to cell index
|
||||
if(it->fileIndex != fileIndex)
|
||||
{
|
||||
// start in cellIndex vermerken
|
||||
int localFileIndex = entriesWithSameFileIndex.begin()->fileIndex;
|
||||
int localCellIndex = cellMap->find(localFileIndex)->second;
|
||||
int localRamIndex = getRAMIndexFromFileIndex(localFileIndex);
|
||||
assert(cellMap->find(entriesWithSameFileIndex.begin()->fileIndex) != cellMap->end());
|
||||
|
||||
cellIndex[localCellIndex] = indexIntoTmpBuffer + fileOffset;
|
||||
indexIntoTmpBuffer += FlushEntriesWithSameFileIndexToBuffer(entriesWithSameFileIndex, tmpBuffer, indexIntoTmpBuffer);
|
||||
entriesWithSameFileIndex.clear(); //todo: in flushEntries erledigen.
|
||||
}
|
||||
GridEdgeData data = *it;
|
||||
entriesWithSameFileIndex.push_back(data);
|
||||
fileIndex = it->fileIndex;
|
||||
}
|
||||
assert(cellMap->find(entriesWithSameFileIndex.begin()->fileIndex) != cellMap->end());
|
||||
int localFileIndex = entriesWithSameFileIndex.begin()->fileIndex;
|
||||
int localCellIndex = cellMap->find(localFileIndex)->second;
|
||||
int localRamIndex = getRAMIndexFromFileIndex(localFileIndex);
|
||||
|
||||
cellIndex[localCellIndex] = indexIntoTmpBuffer + fileOffset;
|
||||
indexIntoTmpBuffer += FlushEntriesWithSameFileIndexToBuffer(entriesWithSameFileIndex, tmpBuffer, indexIntoTmpBuffer);
|
||||
entriesWithSameFileIndex.clear(); //todo: in flushEntries erledigen.
|
||||
|
||||
assert(entriesWithSameFileIndex.size() == 0);
|
||||
|
||||
for(int i = 0; i < 32*32; i++)
|
||||
{
|
||||
indexOutFile.write((char *)&cellIndex[i], sizeof(unsigned));
|
||||
numberOfWrittenBytes += sizeof(unsigned);
|
||||
}
|
||||
|
||||
//write contents of tmpbuffer to disk
|
||||
for(int i = 0; i < indexIntoTmpBuffer; i++)
|
||||
{
|
||||
indexOutFile.write(&tmpBuffer[i], sizeof(char));
|
||||
numberOfWrittenBytes += sizeof(char);
|
||||
}
|
||||
|
||||
delete cellMap;
|
||||
return numberOfWrittenBytes;
|
||||
}
|
||||
|
||||
unsigned FlushEntriesWithSameFileIndexToBuffer(const std::vector<GridEdgeData> &vectorWithSameFileIndex, vector<char>& tmpBuffer, const unsigned index)
|
||||
{
|
||||
unsigned counter = 0;
|
||||
unsigned max = UINT_MAX;
|
||||
|
||||
for(int i = 0; i < vectorWithSameFileIndex.size()-1; i++)
|
||||
{
|
||||
assert( vectorWithSameFileIndex[i].fileIndex == vectorWithSameFileIndex[i+1].fileIndex );
|
||||
assert( vectorWithSameFileIndex[i].ramIndex == vectorWithSameFileIndex[i+1].ramIndex );
|
||||
}
|
||||
|
||||
for(std::vector<GridEdgeData>::const_iterator et = vectorWithSameFileIndex.begin(); et != vectorWithSameFileIndex.end(); et++)
|
||||
{
|
||||
char * start = (char *)&et->edge.start;
|
||||
for(int i = 0; i < sizeof(NodeID); i++)
|
||||
{
|
||||
tmpBuffer[index+counter] = start[i];
|
||||
counter++;
|
||||
}
|
||||
char * target = (char *)&et->edge.target;
|
||||
for(int i = 0; i < sizeof(NodeID); i++)
|
||||
{
|
||||
tmpBuffer[index+counter] = target[i];
|
||||
counter++;
|
||||
}
|
||||
char * slat = (char *) &(et->edge.startCoord.lat);
|
||||
for(int i = 0; i < sizeof(int); i++)
|
||||
{
|
||||
tmpBuffer[index+counter] = slat[i];
|
||||
counter++;
|
||||
}
|
||||
char * slon = (char *) &(et->edge.startCoord.lon);
|
||||
for(int i = 0; i < sizeof(int); i++)
|
||||
{
|
||||
tmpBuffer[index+counter] = slon[i];
|
||||
counter++;
|
||||
}
|
||||
char * tlat = (char *) &(et->edge.targetCoord.lat);
|
||||
for(int i = 0; i < sizeof(int); i++)
|
||||
{
|
||||
tmpBuffer[index+counter] = tlat[i];
|
||||
counter++;
|
||||
}
|
||||
char * tlon = (char *) &(et->edge.targetCoord.lon);
|
||||
for(int i = 0; i < sizeof(int); i++)
|
||||
{
|
||||
tmpBuffer[index+counter] = tlon[i];
|
||||
counter++;
|
||||
}
|
||||
}
|
||||
char * umax = (char *) &max;
|
||||
for(int i = 0; i < sizeof(unsigned); i++)
|
||||
{
|
||||
tmpBuffer[index+counter] = umax[i];
|
||||
counter++;
|
||||
}
|
||||
return counter;
|
||||
}
|
||||
|
||||
void GetContentsOfFileBucket(const unsigned fileIndex, std::vector<_Edge>& result)
|
||||
{
|
||||
unsigned ramIndex = getRAMIndexFromFileIndex(fileIndex);
|
||||
unsigned startIndexInFile = ramIndexTable[ramIndex];
|
||||
if(startIndexInFile == UINT_MAX){
|
||||
return;
|
||||
}
|
||||
|
||||
std::vector<unsigned> cellIndex;
|
||||
cellIndex.resize(32*32);
|
||||
google::dense_hash_map< unsigned, unsigned > * cellMap = new google::dense_hash_map< unsigned, unsigned >(1024);
|
||||
cellMap->set_empty_key(UINT_MAX);
|
||||
|
||||
indexInFile.seekg(startIndexInFile);
|
||||
|
||||
unsigned lineBase = ramIndex/1024;
|
||||
lineBase = lineBase*32*32768;
|
||||
unsigned columnBase = ramIndex%1024;
|
||||
columnBase=columnBase*32;
|
||||
|
||||
for(int i = 0; i < 32; i++)
|
||||
{
|
||||
for(int j = 0; j < 32; j++)
|
||||
{
|
||||
unsigned fileIndex = lineBase + i*32768 + columnBase+j;
|
||||
unsigned cellIndex = i*32+j;
|
||||
cellMap->insert(std::make_pair(fileIndex, cellIndex));
|
||||
}
|
||||
}
|
||||
|
||||
unsigned numOfElementsInCell = 0;
|
||||
for(int i = 0; i < 32*32; i++)
|
||||
{
|
||||
indexInFile.read((char *)&cellIndex[i], sizeof(unsigned));
|
||||
numOfElementsInCell += cellIndex[i];
|
||||
}
|
||||
assert(cellMap->find(fileIndex) != cellMap->end());
|
||||
if(cellIndex[cellMap->find(fileIndex)->second] == UINT_MAX)
|
||||
{
|
||||
return;
|
||||
}
|
||||
unsigned position = cellIndex[cellMap->find(fileIndex)->second] + 32*32*sizeof(unsigned) ;
|
||||
indexInFile.seekg(position);
|
||||
unsigned numberOfEdgesInFileBucket = 0;
|
||||
NodeID start, target; int slat, slon, tlat, tlon;
|
||||
do{
|
||||
indexInFile.read((char *)&(start), sizeof(NodeID));
|
||||
if(start == UINT_MAX || indexInFile.eof())
|
||||
break;
|
||||
indexInFile.read((char *)&(target), sizeof(NodeID));
|
||||
indexInFile.read((char *)&(slat), sizeof(int));
|
||||
indexInFile.read((char *)&(slon), sizeof(int));
|
||||
indexInFile.read((char *)&(tlat), sizeof(int));
|
||||
indexInFile.read((char *)&(tlon), sizeof(int));
|
||||
|
||||
_Edge e(start, target);
|
||||
e.startCoord.lat = slat;
|
||||
e.startCoord.lon = slon;
|
||||
e.targetCoord.lat = tlat;
|
||||
e.targetCoord.lon = tlon;
|
||||
|
||||
result.push_back(e);
|
||||
numberOfEdgesInFileBucket++;
|
||||
} while(true);
|
||||
delete cellMap;
|
||||
}
|
||||
|
||||
/* More or less from monav project, thanks */
|
||||
double ComputeDistance(const _Coordinate& inputPoint, const _Coordinate& source, const _Coordinate& target, _Coordinate& nearest, double *r)
|
||||
{
|
||||
const double vY = (double)target.lon - (double)source.lon;
|
||||
const double vX = (double)target.lat - (double)source.lat;
|
||||
|
||||
const double wY = (double)inputPoint.lon - (double)source.lon;
|
||||
const double wX = (double)inputPoint.lat - (double)source.lat;
|
||||
|
||||
const double lengthSquared = vX * vX + vY * vY;
|
||||
|
||||
if(lengthSquared != 0)
|
||||
{
|
||||
*r = (vX * wX + vY * wY) / lengthSquared;
|
||||
}
|
||||
double percentage = *r;
|
||||
if(*r <=0 ){
|
||||
nearest.lat = source.lat;
|
||||
nearest.lon = source.lon;
|
||||
percentage = 0;
|
||||
return wY * wY + wX * wX;
|
||||
}
|
||||
if( *r>= 1){
|
||||
nearest.lat = target.lat;
|
||||
nearest.lon = target.lon;
|
||||
percentage = 1;
|
||||
const double dY = (double)inputPoint.lon - (double)target.lon;
|
||||
const double dX = (double)inputPoint.lat - (double)target.lat;
|
||||
return dY * dY + dX * dX;
|
||||
}
|
||||
|
||||
nearest.lat = (double)source.lat + ( (*r) * vX );
|
||||
nearest.lon = (double)source.lon + ( (*r) * vY );
|
||||
const double dX = (double)source.lat + (*r) * vX - (double)inputPoint.lat;
|
||||
const double dY = (double)source.lon + (*r) * vY - (double)inputPoint.lon;
|
||||
return dY*dY + dX*dX;
|
||||
}
|
||||
|
||||
ofstream indexOutFile;
|
||||
ifstream indexInFile;
|
||||
ifstream ramInFile;
|
||||
stxxl::vector<GridEdgeData> entries;
|
||||
std::vector<unsigned> ramIndexTable; //4 MB for first level index in RAM
|
||||
};
|
||||
}
|
||||
|
||||
#endif /* NNGRID_H_ */
|
@ -22,6 +22,7 @@ or see http://www.gnu.org/licenses/agpl.txt.
|
||||
#define _NODE_COORDS_H
|
||||
|
||||
#include <cassert>
|
||||
#include <cstddef>
|
||||
#include <limits>
|
||||
|
||||
#include "../typedefs.h"
|
||||
@ -63,4 +64,5 @@ struct NodeCoords {
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
#endif //_NODE_COORDS_H
|
||||
|
@ -21,103 +21,48 @@ or see http://www.gnu.org/licenses/agpl.txt.
|
||||
#ifndef NODEINFORMATIONHELPDESK_H_
|
||||
#define NODEINFORMATIONHELPDESK_H_
|
||||
|
||||
#include <omp.h>
|
||||
|
||||
#include <climits>
|
||||
#include <cstdlib>
|
||||
|
||||
#include <algorithm>
|
||||
#include <deque>
|
||||
#include <fstream>
|
||||
#include <iostream>
|
||||
#include <limits>
|
||||
#include <list>
|
||||
#include <stack>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "../typedefs.h"
|
||||
#include "StaticKDTree.h"
|
||||
#include "NNGrid.h"
|
||||
#include "PhantomNodes.h"
|
||||
|
||||
typedef KDTree::StaticKDTree<2, int, NodeID> KDTreeType;
|
||||
typedef NNGrid::NNGrid Grid;
|
||||
|
||||
class NodeInformationHelpDesk{
|
||||
public:
|
||||
NodeInformationHelpDesk() { int2ExtNodeMap = new vector<KDTreeType::InputPoint>();}
|
||||
KDTreeType * initKDTree(ifstream& input);
|
||||
|
||||
NodeID getExternalNodeID(const NodeID node);
|
||||
void getExternalNodeInfo(const NodeID node, NodeInfo * info) const;
|
||||
int getLatitudeOfNode(const NodeID node) const;
|
||||
int getLongitudeOfNode(const NodeID node) const;
|
||||
|
||||
NodeID getNumberOfNodes() const { return int2ExtNodeMap->size(); }
|
||||
|
||||
inline NodeID findNearestNodeIDForLatLon(const int lat, const int lon, NodeCoords<NodeID> * data) const
|
||||
NodeInformationHelpDesk(const char* ramIndexInput, const char* fileIndexInput) { numberOfNodes = 0; int2ExtNodeMap = new vector<_Coordinate>(); g = new Grid(ramIndexInput,fileIndexInput); }
|
||||
~NodeInformationHelpDesk() { delete int2ExtNodeMap; delete g; }
|
||||
void initNNGrid(ifstream& in)
|
||||
{
|
||||
KDTreeType::InputPoint i;
|
||||
KDTreeType::InputPoint o;
|
||||
i.coordinates[0] = lat;
|
||||
i.coordinates[1] = lon;
|
||||
kdtree->NearestNeighbor(&o, i);
|
||||
data->id = o.data;
|
||||
data->lat = o.coordinates[0];
|
||||
data->lon = o.coordinates[1];
|
||||
return data->id;
|
||||
while(!in.eof())
|
||||
{
|
||||
NodeInfo b;
|
||||
in.read((char *)&b, sizeof(b));
|
||||
int2ExtNodeMap->push_back(_Coordinate(b.lat, b.lon));
|
||||
numberOfNodes++;
|
||||
}
|
||||
in.close();
|
||||
g->OpenIndexFiles();
|
||||
}
|
||||
|
||||
int getLatitudeOfNode(const NodeID node) const { return int2ExtNodeMap->at(node).lat; }
|
||||
|
||||
int getLongitudeOfNode(const NodeID node) const { return int2ExtNodeMap->at(node).lon; }
|
||||
|
||||
NodeID getNumberOfNodes() const { return numberOfNodes; }
|
||||
|
||||
inline void findNearestNodeIDForLatLon(const _Coordinate coord, _Coordinate& result) { result = g->FindNearestPointOnEdge(coord); }
|
||||
|
||||
inline bool FindRoutingStarts(const _Coordinate start, const _Coordinate target, PhantomNodes * phantomNodes) {
|
||||
g->FindRoutingStarts(start, target, phantomNodes);
|
||||
}
|
||||
private:
|
||||
vector<KDTreeType::InputPoint> * int2ExtNodeMap;
|
||||
KDTreeType * kdtree;
|
||||
vector<_Coordinate> * int2ExtNodeMap;
|
||||
Grid * g;
|
||||
unsigned numberOfNodes;
|
||||
};
|
||||
|
||||
//////////////////
|
||||
//implementation//
|
||||
//////////////////
|
||||
|
||||
/* @brief: initialize kd-tree and internal->external node id map
|
||||
*
|
||||
*/
|
||||
KDTreeType * NodeInformationHelpDesk::initKDTree(ifstream& in)
|
||||
{
|
||||
NodeID id = 0;
|
||||
while(!in.eof())
|
||||
{
|
||||
NodeInfo b;
|
||||
in.read((char *)&b, sizeof(b));
|
||||
b.id = id;
|
||||
KDTreeType::InputPoint p;
|
||||
p.coordinates[0] = b.lat;
|
||||
p.coordinates[1] = b.lon;
|
||||
p.data = id;
|
||||
int2ExtNodeMap->push_back(p);
|
||||
id++;
|
||||
}
|
||||
in.close();
|
||||
kdtree = new KDTreeType(int2ExtNodeMap);
|
||||
return kdtree;
|
||||
}
|
||||
|
||||
NodeID NodeInformationHelpDesk::getExternalNodeID(const NodeID node)
|
||||
{
|
||||
|
||||
return int2ExtNodeMap->at(node).data;
|
||||
}
|
||||
|
||||
void NodeInformationHelpDesk::getExternalNodeInfo(const NodeID node, NodeInfo * info) const
|
||||
{
|
||||
info->id = int2ExtNodeMap->at(node).data;
|
||||
info->lat = int2ExtNodeMap->at(node).coordinates[0];
|
||||
info->lon = int2ExtNodeMap->at(node).coordinates[1];
|
||||
}
|
||||
|
||||
int NodeInformationHelpDesk::getLatitudeOfNode(const NodeID node) const
|
||||
{
|
||||
return int2ExtNodeMap->at(node).coordinates[0];
|
||||
}
|
||||
|
||||
int NodeInformationHelpDesk::getLongitudeOfNode(const NodeID node) const
|
||||
{
|
||||
return int2ExtNodeMap->at(node).coordinates[1];
|
||||
}
|
||||
|
||||
#endif /*NODEINFORMATIONHELPDESK_H_*/
|
||||
|
90
DataStructures/Percent.h
Normal file
90
DataStructures/Percent.h
Normal file
@ -0,0 +1,90 @@
|
||||
/*
|
||||
open source routing machine
|
||||
Copyright (C) Dennis Luxen, others 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.
|
||||
*/
|
||||
|
||||
#ifndef PERCENT_H
|
||||
#define PERCENT_H
|
||||
|
||||
#include <iostream>
|
||||
#ifdef _OPENMP
|
||||
#include <omp.h>
|
||||
#endif
|
||||
|
||||
class Percent
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* Constructor.
|
||||
* @param maxValue the value that corresponds to 100%
|
||||
* @param step the progress is shown in steps of 'step' percent
|
||||
*/
|
||||
Percent(unsigned maxValue, unsigned step = 5) {
|
||||
reinit(maxValue, step);
|
||||
}
|
||||
|
||||
/** Reinitializes this object. */
|
||||
void reinit(unsigned maxValue, unsigned step = 5) {
|
||||
_maxValue = maxValue;
|
||||
_current_value = 0;
|
||||
_intervalPercent = _maxValue / 100;
|
||||
_nextThreshold = _intervalPercent;
|
||||
_lastPercent = 0;
|
||||
_step = step;
|
||||
}
|
||||
|
||||
/** If there has been significant progress, display it. */
|
||||
void printStatus(unsigned currentValue) {
|
||||
if (currentValue >= _nextThreshold) {
|
||||
_nextThreshold += _intervalPercent;
|
||||
printPercent( currentValue / (double)_maxValue * 100 );
|
||||
}
|
||||
if (currentValue + 1 == _maxValue)
|
||||
std::cout << " 100%" << std::endl;
|
||||
}
|
||||
|
||||
void printIncrement()
|
||||
{
|
||||
#pragma omp atomic
|
||||
_current_value++;
|
||||
printStatus(_current_value);
|
||||
}
|
||||
private:
|
||||
unsigned _current_value;
|
||||
unsigned _maxValue;
|
||||
unsigned _intervalPercent;
|
||||
unsigned _nextThreshold;
|
||||
unsigned _lastPercent;
|
||||
unsigned _step;
|
||||
|
||||
/** Displays the new progress. */
|
||||
void printPercent(double percent) {
|
||||
while (percent >= _lastPercent+_step) {
|
||||
_lastPercent+=_step;
|
||||
if (_lastPercent % 10 == 0) {
|
||||
std::cout << " " << _lastPercent << "% ";
|
||||
}
|
||||
else {
|
||||
std::cout << ".";
|
||||
}
|
||||
std::cout.flush();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
#endif // PERCENT_H
|
38
DataStructures/PhantomNodes.h
Normal file
38
DataStructures/PhantomNodes.h
Normal file
@ -0,0 +1,38 @@
|
||||
/*
|
||||
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.
|
||||
*/
|
||||
|
||||
#ifndef PHANTOMNODES_H_
|
||||
#define PHANTOMNODES_H_
|
||||
|
||||
#include "ExtractorStructs.h"
|
||||
|
||||
struct PhantomNodes {
|
||||
PhantomNodes() : startNode1(UINT_MAX), startNode2(UINT_MAX), targetNode1(UINT_MAX), targetNode2(UINT_MAX), startRatio(1.), targetRatio(1.) {}
|
||||
NodeID startNode1;
|
||||
NodeID startNode2;
|
||||
NodeID targetNode1;
|
||||
NodeID targetNode2;
|
||||
double startRatio;
|
||||
double targetRatio;
|
||||
_Coordinate startCoord;
|
||||
_Coordinate targetCoord;
|
||||
};
|
||||
|
||||
#endif /* PHANTOMNODES_H_ */
|
@ -21,6 +21,8 @@ or see http://www.gnu.org/licenses/agpl.txt.
|
||||
#ifndef TIMEUTIL_H_
|
||||
#define TIMEUTIL_H_
|
||||
|
||||
#include <climits>
|
||||
#include <cstdlib>
|
||||
#include <sys/time.h>
|
||||
|
||||
/** Returns a timestamp (now) in seconds (incl. a fractional part). */
|
||||
|
@ -16,7 +16,7 @@ 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.
|
||||
*/
|
||||
*/
|
||||
|
||||
#ifndef HTTP_ROUTER_REQUEST_HANDLER_HPP
|
||||
#define HTTP_ROUTER_REQUEST_HANDLER_HPP
|
||||
@ -58,8 +58,8 @@ public:
|
||||
std::size_t last_amp_pos = request.find_last_of("&");
|
||||
int lat = static_cast<int>(100000*atof(request.substr(first_amp_pos+1, request.length()-last_amp_pos-1).c_str()));
|
||||
int lon = static_cast<int>(100000*atof(request.substr(last_amp_pos+1).c_str()));
|
||||
NodeCoords<NodeID> * data = new NodeCoords<NodeID>();
|
||||
NodeID start = sEngine->findNearestNodeForLatLon(lat, lon, data);
|
||||
_Coordinate result;
|
||||
sEngine->findNearestNodeForLatLon(_Coordinate(lat, lon), result);
|
||||
|
||||
rep.status = reply::ok;
|
||||
rep.content.append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
|
||||
@ -68,13 +68,13 @@ public:
|
||||
|
||||
std::stringstream out1;
|
||||
out1 << setprecision(10);
|
||||
out1 << "<name>Nearest Place in map to " << lat/100000. << "," << lon/100000. << ": node with id " << start << "</name>";
|
||||
out1 << "<name>Nearest Place in map to " << lat/100000. << "," << lon/100000. << "</name>";
|
||||
rep.content.append(out1.str());
|
||||
rep.content.append("<Point>");
|
||||
|
||||
std::stringstream out2;
|
||||
out2 << setprecision(10);
|
||||
out2 << "<coordinates>" << data->lon / 100000. << "," << data->lat / 100000. << "</coordinates>";
|
||||
out2 << "<coordinates>" << result.lon / 100000. << "," << result.lat / 100000. << "</coordinates>";
|
||||
rep.content.append(out2.str());
|
||||
rep.content.append("</Point>");
|
||||
rep.content.append("</Placemark>");
|
||||
@ -87,7 +87,6 @@ public:
|
||||
rep.headers[1].value = "application/vnd.google-earth.kml+xml";
|
||||
rep.headers[2].name = "Content-Disposition";
|
||||
rep.headers[2].value = "attachment; filename=\"placemark.kml\"";
|
||||
delete data;
|
||||
return;
|
||||
}
|
||||
if(command == "route")
|
||||
@ -102,12 +101,12 @@ public:
|
||||
int lat2 = static_cast<int>(100000*atof(request.substr(third_amp_pos+1, request.length()-fourth_amp_pos-1).c_str()));
|
||||
int lon2 = static_cast<int>(100000*atof(request.substr(fourth_amp_pos+1).c_str()));
|
||||
|
||||
NodeCoords<NodeID> * startData = new NodeCoords<NodeID>();
|
||||
NodeCoords<NodeID> * targetData = new NodeCoords<NodeID>();
|
||||
_Coordinate startCoord(lat1, lon1);
|
||||
_Coordinate targetCoord(lat2, lon2);
|
||||
vector<NodeID> * path = new vector<NodeID>();
|
||||
NodeID start = sEngine->findNearestNodeForLatLon(lat1, lon1, startData);
|
||||
NodeID target = sEngine->findNearestNodeForLatLon(lat2, lon2, targetData);
|
||||
unsigned int distance = sEngine->ComputeRoute(start, target, path);
|
||||
PhantomNodes * phantomNodes = new PhantomNodes();
|
||||
sEngine->FindRoutingStarts(startCoord, targetCoord, phantomNodes);
|
||||
unsigned int distance = sEngine->ComputeRoute(phantomNodes, path, startCoord, targetCoord);
|
||||
|
||||
rep.status = reply::ok;
|
||||
rep.content.append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
|
||||
@ -124,19 +123,29 @@ public:
|
||||
rep.content.append("<tessellate>1</tessellate>");
|
||||
rep.content.append("<altitudeMode>absolute</altitudeMode>");
|
||||
rep.content.append("<coordinates>\n");
|
||||
|
||||
if(distance != std::numeric_limits<unsigned int>::max())
|
||||
{ //A route has been found
|
||||
NodeInfo * info = new NodeInfo();
|
||||
stringstream startOut;
|
||||
startOut << std::setprecision(10);
|
||||
startOut << phantomNodes->startCoord.lon/100000. << "," << phantomNodes->startCoord.lat/100000. << " \n";
|
||||
rep.content.append(startOut.str());
|
||||
|
||||
_Coordinate result;
|
||||
for(vector<NodeID>::iterator it = path->begin(); it != path->end(); it++)
|
||||
{
|
||||
sEngine-> getNodeInfo(*it, info);
|
||||
sEngine-> getNodeInfo(*it, result);
|
||||
stringstream nodeout;
|
||||
nodeout << std::setprecision(10);
|
||||
nodeout << info->lon/100000. << "," << info->lat/100000. << " " << endl;
|
||||
nodeout << result.lon/100000. << "," << result.lat/100000. << " " << "\n";
|
||||
rep.content.append(nodeout.str());
|
||||
}
|
||||
delete info;
|
||||
stringstream targetOut;
|
||||
targetOut << std::setprecision(10);
|
||||
targetOut << phantomNodes->targetCoord.lon/100000. << "," << phantomNodes->targetCoord.lat/100000. << " \n";
|
||||
rep.content.append(targetOut.str());
|
||||
}
|
||||
|
||||
rep.content.append("</coordinates>");
|
||||
rep.content.append("</LineString>");
|
||||
rep.content.append("</Placemark>");
|
||||
@ -150,6 +159,9 @@ public:
|
||||
rep.headers[1].value = "application/vnd.google-earth.kml+xml";
|
||||
rep.headers[2].name = "Content-Disposition";
|
||||
rep.headers[2].value = "attachment; filename=\"route.kml\"";
|
||||
|
||||
delete path;
|
||||
delete phantomNodes;
|
||||
return;
|
||||
}
|
||||
rep = reply::stock_reply(reply::bad_request);
|
||||
|
@ -16,13 +16,18 @@ 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>
|
||||
@ -42,10 +47,13 @@ or see http://www.gnu.org/licenses/agpl.txt.
|
||||
#include "Contractor/ContractionCleanup.h"
|
||||
#include "Contractor/DynamicGraph.h"
|
||||
|
||||
#include "DataStructures/NNGrid.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
typedef ContractionCleanup::Edge::EdgeData EdgeData;
|
||||
typedef DynamicGraph<EdgeData>::InputEdge GridEdge;
|
||||
typedef NNGrid::NNGrid Grid;
|
||||
|
||||
vector<NodeInfo> * int2ExtNodeMap = new vector<NodeInfo>();
|
||||
|
||||
@ -69,16 +77,48 @@ int main (int argc, char *argv[])
|
||||
|
||||
char nodeOut[1024];
|
||||
char edgeOut[1024];
|
||||
char ramIndexOut[1024];
|
||||
char fileIndexOut[1024];
|
||||
strcpy(nodeOut, argv[1]);
|
||||
strcpy(edgeOut, argv[1]);
|
||||
strcpy(ramIndexOut, argv[1]);
|
||||
strcpy(fileIndexOut, argv[1]);
|
||||
|
||||
strcat(nodeOut, ".nodes");
|
||||
strcat(edgeOut, ".hsgr");
|
||||
strcat(ramIndexOut, ".ramIndex");
|
||||
strcat(fileIndexOut, ".fileIndex");
|
||||
ofstream mapOutFile(nodeOut, ios::binary);
|
||||
|
||||
Grid * g = new Grid();
|
||||
cout << "building grid ..." << flush;
|
||||
Percent p(edgeList.size());
|
||||
for(NodeID i = 0; i < edgeList.size(); i++)
|
||||
{
|
||||
p.printIncrement();
|
||||
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;
|
||||
|
||||
//Serializing the node map.
|
||||
for(NodeID i = 0; i < int2ExtNodeMap->size(); i++)
|
||||
{
|
||||
//mapOutFile.write((char *)&(i), sizeof(NodeID));
|
||||
mapOutFile.write((char *)&(int2ExtNodeMap->at(i)), sizeof(NodeInfo));
|
||||
}
|
||||
mapOutFile.close();
|
||||
@ -86,8 +126,6 @@ int main (int argc, char *argv[])
|
||||
|
||||
Contractor* contractor = new Contractor( n, edgeList );
|
||||
|
||||
// cout << "Number of connected components: " << contractor->GetNumberOfComponents() << endl;
|
||||
|
||||
contractor->Run();
|
||||
|
||||
contractor->checkForAllOrigEdges(edgeList);
|
||||
|
@ -37,7 +37,7 @@ or see http://www.gnu.org/licenses/agpl.txt.
|
||||
|
||||
#include "typedefs.h"
|
||||
#include "DataStructures/InputReaderFactory.h"
|
||||
#include "DataStructures/extractorStructs.h"
|
||||
#include "DataStructures/ExtractorStructs.h"
|
||||
|
||||
using namespace std;
|
||||
typedef google::dense_hash_map<NodeID, _Node> NodeMap;
|
||||
|
33
routed.cpp
33
routed.cpp
@ -41,7 +41,7 @@ or see http://www.gnu.org/licenses/agpl.txt.
|
||||
using namespace std;
|
||||
|
||||
typedef ContractionCleanup::Edge::EdgeData EdgeData;
|
||||
typedef StaticGraph<EdgeData>::InputEdge GraphEdge;
|
||||
typedef StaticGraph<EdgeData>::InputEdge GridEdge;
|
||||
typedef http::server<StaticGraph<EdgeData> > server;
|
||||
|
||||
/*
|
||||
@ -52,27 +52,23 @@ int main (int argc, char *argv[])
|
||||
{
|
||||
double time;
|
||||
|
||||
if(argc < 2)
|
||||
if(argc < 4)
|
||||
{
|
||||
cerr << "Correct usage:" << endl << argv[0] << " <hsgr data> <nodes data>" << endl;
|
||||
cerr << "Correct usage:" << endl << argv[0] << " <hsgr data> <nodes data> <ram index> <file index>" << endl;
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
if (argv[0] == 0) {
|
||||
cerr << "Missing data files!" << endl;
|
||||
return -1;
|
||||
}
|
||||
ifstream in(argv[1], ios::binary);
|
||||
ifstream in2(argv[2], ios::binary);
|
||||
NodeInformationHelpDesk * kdtreeService = new NodeInformationHelpDesk();
|
||||
NodeInformationHelpDesk * nodeInfoHelper = new NodeInformationHelpDesk(argv[3], argv[4]);
|
||||
|
||||
time = get_timestamp();
|
||||
cout << "deserializing edge data from " << argv[1] << " ..." << flush;
|
||||
|
||||
std::vector< GraphEdge> edgelist;
|
||||
std::vector< GridEdge> * edgelist = new std::vector< GridEdge>();
|
||||
while(!in.eof())
|
||||
{
|
||||
GraphEdge g;
|
||||
GridEdge g;
|
||||
EdgeData e;
|
||||
|
||||
int distance;
|
||||
@ -94,19 +90,18 @@ int main (int argc, char *argv[])
|
||||
e.backward = backward; e.distance = distance; e.forward = forward; e.middle = middle; e.shortcut = shortcut;
|
||||
g.data = e; g.source = source; g.target = target;
|
||||
|
||||
edgelist.push_back(g);
|
||||
edgelist->push_back(g);
|
||||
}
|
||||
|
||||
in.close();
|
||||
cout << "in " << get_timestamp() - time << "s" << endl;
|
||||
cout << "search graph has " << edgelist.size() << " edges" << endl;
|
||||
time = get_timestamp();
|
||||
cout << "deserializing node map and building kd-tree ..." << flush;
|
||||
kdtreeService->initKDTree(in2);
|
||||
cout << "deserializing node map and building nearest neighbor grid ..." << flush;
|
||||
nodeInfoHelper->initNNGrid(in2);
|
||||
cout << "in " << get_timestamp() - time << "s" << endl;
|
||||
|
||||
time = get_timestamp();
|
||||
StaticGraph<EdgeData> * graph = new StaticGraph<EdgeData>(kdtreeService->getNumberOfNodes()-1, edgelist);
|
||||
StaticGraph<EdgeData> * graph = new StaticGraph<EdgeData>(nodeInfoHelper->getNumberOfNodes()-1, *edgelist);
|
||||
delete edgelist;
|
||||
cout << "checking data sanity ..." << flush;
|
||||
NodeID numberOfNodes = graph->GetNumberOfNodes();
|
||||
for ( NodeID node = 0; node < numberOfNodes; ++node ) {
|
||||
@ -139,7 +134,7 @@ int main (int argc, char *argv[])
|
||||
time = get_timestamp();
|
||||
cout << "building search graph ..." << flush;
|
||||
|
||||
SearchEngine<EdgeData, StaticGraph<EdgeData> > * sEngine = new SearchEngine<EdgeData, StaticGraph<EdgeData> >(graph, kdtreeService);
|
||||
SearchEngine<EdgeData, StaticGraph<EdgeData> > * sEngine = new SearchEngine<EdgeData, StaticGraph<EdgeData> >(graph, nodeInfoHelper);
|
||||
cout << "in " << get_timestamp() - time << "s" << endl;
|
||||
|
||||
time = get_timestamp();
|
||||
@ -178,6 +173,8 @@ int main (int argc, char *argv[])
|
||||
std::cerr << "exception: " << e.what() << "\n";
|
||||
}
|
||||
cout << "graceful shutdown after " << get_timestamp() - time << "s" << endl;
|
||||
delete kdtreeService;
|
||||
delete sEngine;
|
||||
delete graph;
|
||||
delete nodeInfoHelper;
|
||||
return 0;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user