diff --git a/Contractor/ContractionCleanup.h b/Contractor/ContractionCleanup.h index 195833913..c5cbdcecb 100644 --- a/Contractor/ContractionCleanup.h +++ b/Contractor/ContractionCleanup.h @@ -58,7 +58,6 @@ private: } }; - public: struct Edge { diff --git a/Contractor/Contractor.h b/Contractor/Contractor.h index ffbf3edf0..cb4428713 100644 --- a/Contractor/Contractor.h +++ b/Contractor/Contractor.h @@ -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); } diff --git a/Contractor/SearchEngine.h b/Contractor/SearchEngine.h index 9ac9455ec..9a56d0c2a 100644 --- a/Contractor/SearchEngine.h +++ b/Contractor/SearchEngine.h @@ -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 #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 +template 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 * path) + unsigned int ComputeRoute(PhantomNodes * phantomNodes, vector * 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::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 * 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) diff --git a/DataStructures/extractorStructs.h b/DataStructures/ExtractorStructs.h similarity index 96% rename from DataStructures/extractorStructs.h rename to DataStructures/ExtractorStructs.h index 4a12faae1..83af87367 100644 --- a/DataStructures/extractorStructs.h +++ b/DataStructures/ExtractorStructs.h @@ -23,6 +23,8 @@ or see http://www.gnu.org/licenses/agpl.txt. #include #include +#include +#include /* 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(100000*atof(( const char* ) attribute ) ); + node.lat = static_cast(100000.*atof(( const char* ) attribute ) ); xmlFree( attribute ); } attribute = xmlTextReaderGetAttribute( inputReader, ( const xmlChar* ) "lon" ); if ( attribute != NULL ) { - node.lon = static_cast(100000*atof(( const char* ) attribute )); + node.lon = static_cast(100000.*atof(( const char* ) attribute )); xmlFree( attribute ); } attribute = xmlTextReaderGetAttribute( inputReader, ( const xmlChar* ) "id" ); diff --git a/DataStructures/GridEdge.h b/DataStructures/GridEdge.h new file mode 100644 index 000000000..ee2b6239f --- /dev/null +++ b/DataStructures/GridEdge.h @@ -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_ */ diff --git a/DataStructures/InputReaderFactory.h b/DataStructures/InputReaderFactory.h index 1e63d2981..3e4b36ec0 100644 --- a/DataStructures/InputReaderFactory.h +++ b/DataStructures/InputReaderFactory.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; diff --git a/DataStructures/NNGrid.h b/DataStructures/NNGrid.h new file mode 100644 index 000000000..e37493cc3 --- /dev/null +++ b/DataStructures/NNGrid.h @@ -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 + +#include +#include +#include +#include +#include +#include + +#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 > &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 > &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 > 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 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::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::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::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::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& entriesWithSameRAMIndex, unsigned fileOffset ) + { + vector tmpBuffer; + tmpBuffer.resize(32*32*4096,0); + unsigned indexIntoTmpBuffer = 0; + unsigned numberOfWrittenBytes = 0; + assert(indexOutFile.is_open()); + + vector 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::iterator uniqueEnd = std::unique(entriesWithSameRAMIndex.begin(), entriesWithSameRAMIndex.end()); + + //traverse each file bucket and write its contents to disk + std::vector entriesWithSameFileIndex; + unsigned fileIndex = entriesWithSameRAMIndex.begin()->fileIndex; + + for(std::vector::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 &vectorWithSameFileIndex, vector& 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::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 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 entries; + std::vector ramIndexTable; //4 MB for first level index in RAM +}; +} + +#endif /* NNGRID_H_ */ diff --git a/DataStructures/NodeCoords.h b/DataStructures/NodeCoords.h index 7032eabe6..bfdcb2ed0 100644 --- a/DataStructures/NodeCoords.h +++ b/DataStructures/NodeCoords.h @@ -22,6 +22,7 @@ or see http://www.gnu.org/licenses/agpl.txt. #define _NODE_COORDS_H #include +#include #include #include "../typedefs.h" @@ -63,4 +64,5 @@ struct NodeCoords { } } }; + #endif //_NODE_COORDS_H diff --git a/DataStructures/NodeInformationHelpDesk.h b/DataStructures/NodeInformationHelpDesk.h index 3c4bd7f11..b709a1e5a 100644 --- a/DataStructures/NodeInformationHelpDesk.h +++ b/DataStructures/NodeInformationHelpDesk.h @@ -21,103 +21,48 @@ or see http://www.gnu.org/licenses/agpl.txt. #ifndef NODEINFORMATIONHELPDESK_H_ #define NODEINFORMATIONHELPDESK_H_ -#include - -#include -#include - -#include -#include #include #include -#include -#include -#include -#include #include #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 * 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 * 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 * 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_*/ diff --git a/DataStructures/Percent.h b/DataStructures/Percent.h new file mode 100644 index 000000000..fee385434 --- /dev/null +++ b/DataStructures/Percent.h @@ -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 +#ifdef _OPENMP +#include +#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 diff --git a/DataStructures/PhantomNodes.h b/DataStructures/PhantomNodes.h new file mode 100644 index 000000000..76d0bc5c3 --- /dev/null +++ b/DataStructures/PhantomNodes.h @@ -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_ */ diff --git a/DataStructures/Util.h b/DataStructures/Util.h index 8a1a25bdf..3666e52db 100644 --- a/DataStructures/Util.h +++ b/DataStructures/Util.h @@ -21,6 +21,8 @@ or see http://www.gnu.org/licenses/agpl.txt. #ifndef TIMEUTIL_H_ #define TIMEUTIL_H_ +#include +#include #include /** Returns a timestamp (now) in seconds (incl. a fractional part). */ diff --git a/HttpServer/request_handler.h b/HttpServer/request_handler.h index 9a4afcc76..8902b0c8c 100644 --- a/HttpServer/request_handler.h +++ b/HttpServer/request_handler.h @@ -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(100000*atof(request.substr(first_amp_pos+1, request.length()-last_amp_pos-1).c_str())); int lon = static_cast(100000*atof(request.substr(last_amp_pos+1).c_str())); - NodeCoords * data = new NodeCoords(); - NodeID start = sEngine->findNearestNodeForLatLon(lat, lon, data); + _Coordinate result; + sEngine->findNearestNodeForLatLon(_Coordinate(lat, lon), result); rep.status = reply::ok; rep.content.append(""); @@ -68,13 +68,13 @@ public: std::stringstream out1; out1 << setprecision(10); - out1 << "Nearest Place in map to " << lat/100000. << "," << lon/100000. << ": node with id " << start << ""; + out1 << "Nearest Place in map to " << lat/100000. << "," << lon/100000. << ""; rep.content.append(out1.str()); rep.content.append(""); std::stringstream out2; out2 << setprecision(10); - out2 << "" << data->lon / 100000. << "," << data->lat / 100000. << ""; + out2 << "" << result.lon / 100000. << "," << result.lat / 100000. << ""; rep.content.append(out2.str()); rep.content.append(""); rep.content.append(""); @@ -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(100000*atof(request.substr(third_amp_pos+1, request.length()-fourth_amp_pos-1).c_str())); int lon2 = static_cast(100000*atof(request.substr(fourth_amp_pos+1).c_str())); - NodeCoords * startData = new NodeCoords(); - NodeCoords * targetData = new NodeCoords(); + _Coordinate startCoord(lat1, lon1); + _Coordinate targetCoord(lat2, lon2); vector * path = new vector(); - 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(""); @@ -124,19 +123,29 @@ public: rep.content.append("1"); rep.content.append("absolute"); rep.content.append("\n"); + if(distance != std::numeric_limits::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::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(""); rep.content.append(""); rep.content.append(""); @@ -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); diff --git a/createHierarchy.cpp b/createHierarchy.cpp index b05a383f8..0f28ba5ad 100644 --- a/createHierarchy.cpp +++ b/createHierarchy.cpp @@ -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 #include #include @@ -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::InputEdge GridEdge; +typedef NNGrid::NNGrid Grid; vector * int2ExtNodeMap = new vector(); @@ -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); diff --git a/extractLargeNetwork.cpp b/extractLargeNetwork.cpp index 75f1c0292..463fb3b99 100644 --- a/extractLargeNetwork.cpp +++ b/extractLargeNetwork.cpp @@ -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 NodeMap; diff --git a/routed.cpp b/routed.cpp index 761c9d54e..c9edcdf4f 100644 --- a/routed.cpp +++ b/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::InputEdge GraphEdge; +typedef StaticGraph::InputEdge GridEdge; typedef http::server > 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] << " " << endl; + cerr << "Correct usage:" << endl << argv[0] << " " << 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 * graph = new StaticGraph(kdtreeService->getNumberOfNodes()-1, edgelist); + StaticGraph * graph = new StaticGraph(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 > * sEngine = new SearchEngine >(graph, kdtreeService); + SearchEngine > * sEngine = new SearchEngine >(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; }