merge conflict CMakeLists.txt

This commit is contained in:
DennisOSRM 2013-07-09 13:38:44 +02:00
commit 51a7d3ff50
70 changed files with 946 additions and 1449 deletions

1
.gitignore vendored
View File

@ -72,6 +72,7 @@ stxxl.errlog
/osrm-extract
/osrm-routed
/osrm-prepare
/osrm-cli
/nohup.out
# Sandbox folder #

View File

@ -23,9 +23,10 @@ or see http://www.gnu.org/licenses/agpl.txt.
#include <cmath>
#include <vector>
typedef std::pair<unsigned, unsigned> BresenhamPixel;
inline void Bresenham (int x0, int y0, int x1, int y1, std::vector<BresenhamPixel> &resultList) {
inline void Bresenham (int x0, int y0, const int x1, int const y1, std::vector<BresenhamPixel> &resultList) {
int dx = std::abs(x1-x0);
int dy = std::abs(y1-y0);
int sx = (x0 < x1 ? 1 : -1);

View File

@ -21,12 +21,13 @@ or see http://www.gnu.org/licenses/agpl.txt.
#ifndef DOUGLASPEUCKER_H_
#define DOUGLASPEUCKER_H_
#include "../DataStructures/Coordinate.h"
#include <cassert>
#include <cmath>
#include <cfloat>
#include <stack>
#include "../DataStructures/Coordinate.h"
#include <vector>
/*This class object computes the bitvector of indicating generalized input points
* according to the (Ramer-)Douglas-Peucker algorithm.

View File

@ -21,6 +21,9 @@ or see http://www.gnu.org/licenses/agpl.txt.
#ifndef OBJECTTOBASE64_H_
#define OBJECTTOBASE64_H_
#include "../Util/StringUtil.h"
#include <boost/assert.hpp>
#include <boost/archive/iterators/base64_from_binary.hpp>
#include <boost/archive/iterators/binary_from_base64.hpp>
#include <boost/archive/iterators/transform_width.hpp>
@ -28,40 +31,63 @@ or see http://www.gnu.org/licenses/agpl.txt.
#include <algorithm>
#include <string>
#include "../Util/StringUtil.h"
#include <vector>
typedef
boost::archive::iterators::base64_from_binary<
boost::archive::iterators::transform_width<std::string::const_iterator, 6, 8>
> base64_t;
boost::archive::iterators::transform_width<const char *, 6, 8>
> base64_t;
typedef
boost::archive::iterators::transform_width<
boost::archive::iterators::binary_from_base64<std::string::const_iterator>, 8, 6
boost::archive::iterators::binary_from_base64<
std::string::const_iterator>, 8, 6
> binary_t;
template<class ToEncodeT>
static void EncodeObjectToBase64(const ToEncodeT & object, std::string& encoded) {
encoded.clear();
char * pointerToOriginalObject = (char *)&object;
encoded = std::string(base64_t(pointerToOriginalObject), base64_t(pointerToOriginalObject+sizeof(ToEncodeT)));
//replace "+" with "-" and "/" with "_"
template<class ObjectT>
static void EncodeObjectToBase64(const ObjectT & object, std::string& encoded) {
const char * char_ptr_to_object = (const char *)&object;
std::vector<unsigned char> data(sizeof(object));
std::copy(
char_ptr_to_object,
char_ptr_to_object + sizeof(ObjectT),
data.begin()
);
unsigned char number_of_padded_chars = 0; // is in {0,1,2};
while(data.size() % 3 != 0) {
++number_of_padded_chars;
data.push_back(0x00);
}
BOOST_ASSERT_MSG(
0 == data.size() % 3,
"base64 input data size is not a multiple of 3!"
);
encoded.resize(sizeof(ObjectT));
encoded.assign(
base64_t( &data[0] ),
base64_t( &data[0] + (data.size() - number_of_padded_chars) )
);
replaceAll(encoded, "+", "-");
replaceAll(encoded, "/", "_");
}
template<class ToEncodeT>
static void DecodeObjectFromBase64(ToEncodeT & object, const std::string& _encoded) {
template<class ObjectT>
static void DecodeObjectFromBase64(const std::string& input, ObjectT & object) {
try {
std::string encoded(_encoded);
std::string encoded(input);
//replace "-" with "+" and "_" with "/"
replaceAll(encoded, "-", "+");
replaceAll(encoded, "_", "/");
char * pointerToDecodedObject = (char *)&object;
std::string dec(binary_t(encoded.begin()), binary_t(encoded.begin() + encoded.length() - 1));
std::copy ( dec.begin(), dec.end(), pointerToDecodedObject );
} catch(...) {}
std::copy (
binary_t( encoded.begin() ),
binary_t( encoded.begin() + encoded.length() - 1),
(char *)&object
);
} catch(...) { }
}
#endif /* OBJECTTOBASE64_H_ */

View File

@ -21,12 +21,11 @@ or see http://www.gnu.org/licenses/agpl.txt.
#ifndef POLYLINECOMPRESSOR_H_
#define POLYLINECOMPRESSOR_H_
#include <string>
//#include "../DataStructures/ExtractorStructs.h"
#include "../DataStructures/SegmentInformation.h"
#include "../Util/StringUtil.h"
#include <string>
class PolylineCompressor {
private:
inline void encodeVectorSignedNumber(std::vector<int> & numbers, std::string & output) const {

View File

@ -16,25 +16,15 @@ 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.
Strongly connected components using Tarjan's Algorithm
*/
#ifndef STRONGLYCONNECTEDCOMPONENTS_H_
#define STRONGLYCONNECTEDCOMPONENTS_H_
#include <cassert>
#include <stack>
#include <vector>
#include <boost/foreach.hpp>
#include <boost/make_shared.hpp>
#include <boost/unordered_map.hpp>
#include <gdal/gdal.h>
#include <gdal/ogrsf_frmts.h>
#include "../DataStructures/Coordinate.h"
#include "../DataStructures/DeallocatingVector.h"
#include "../DataStructures/DynamicGraph.h"
#include "../DataStructures/ImportEdge.h"
@ -43,11 +33,34 @@ or see http://www.gnu.org/licenses/agpl.txt.
#include "../DataStructures/Restriction.h"
#include "../DataStructures/TurnInstructions.h"
// Strongly connected components using Tarjan's Algorithm
#include <boost/filesystem.hpp>
#include <boost/foreach.hpp>
#include <boost/integer.hpp>
#include <boost/make_shared.hpp>
#include <boost/unordered_map.hpp>
#ifdef __APPLE__
#include <gdal.h>
#include <ogrsf_frmts.h>
#else
#include <gdal/gdal.h>
#include <gdal/ogrsf_frmts.h>
#endif
#include <cassert>
#include <stack>
#include <vector>
class TarjanSCC {
private:
struct _NodeBasedEdgeData {
struct TarjanNode {
TarjanNode() : index(UINT_MAX), lowlink(UINT_MAX), onStack(false) {}
unsigned index;
unsigned lowlink;
bool onStack;
};
struct TarjanEdgeData {
int distance;
unsigned edgeBasedNodeID;
unsigned nameID:31;
@ -58,25 +71,31 @@ private:
bool backward:1;
bool roundabout:1;
bool ignoreInGrid:1;
bool reversedEdge:1;
};
typedef DynamicGraph< _NodeBasedEdgeData > _NodeBasedDynamicGraph;
typedef _NodeBasedDynamicGraph::InputEdge _NodeBasedEdge;
std::vector<NodeInfo> inputNodeInfoList;
unsigned numberOfTurnRestrictions;
boost::shared_ptr<_NodeBasedDynamicGraph> _nodeBasedGraph;
boost::unordered_map<NodeID, bool> _barrierNodes;
boost::unordered_map<NodeID, bool> _trafficLights;
struct TarjanStackFrame {
explicit TarjanStackFrame(NodeID _v, NodeID p) : v(_v), parent(p) {}
NodeID v;
NodeID parent;
};
typedef DynamicGraph<TarjanEdgeData> TarjanDynamicGraph;
typedef TarjanDynamicGraph::InputEdge TarjanEdge;
typedef std::pair<NodeID, NodeID> RestrictionSource;
typedef std::pair<NodeID, bool> RestrictionTarget;
typedef std::vector<RestrictionTarget> EmanatingRestrictionsVector;
typedef boost::unordered_map<RestrictionSource, unsigned > RestrictionMap;
std::vector<NodeInfo> inputNodeInfoList;
unsigned numberOfTurnRestrictions;
boost::shared_ptr<TarjanDynamicGraph> _nodeBasedGraph;
boost::unordered_map<NodeID, bool> _barrierNodes;
boost::unordered_map<NodeID, bool> _trafficLights;
std::vector<EmanatingRestrictionsVector> _restrictionBucketVector;
RestrictionMap _restrictionMap;
public:
struct EdgeBasedNode {
bool operator<(const EdgeBasedNode & other) const {
return other.id < id;
@ -95,21 +114,7 @@ public:
bool ignoreInGrid:1;
};
private:
DeallocatingVector<EdgeBasedNode> edgeBasedNodes;
struct TarjanNode {
TarjanNode() : index(UINT_MAX), lowlink(UINT_MAX), onStack(false) {}
unsigned index;
unsigned lowlink;
bool onStack;
};
struct TarjanStackFrame {
explicit TarjanStackFrame(NodeID _v, NodeID p) : v(_v), parent(p) {}
NodeID v;
NodeID parent;
};
public:
TarjanSCC(int nodes, std::vector<NodeBasedEdge> & inputEdges, std::vector<NodeID> & bn, std::vector<NodeID> & tl, std::vector<_Restriction> & irs, std::vector<NodeInfo> & nI) : inputNodeInfoList(nI), numberOfTurnRestrictions(irs.size()) {
BOOST_FOREACH(_Restriction & restriction, irs) {
@ -141,10 +146,10 @@ public:
_trafficLights[id] = true;
}
DeallocatingVector< _NodeBasedEdge > edges;
DeallocatingVector< TarjanEdge > edges;
for ( std::vector< NodeBasedEdge >::const_iterator i = inputEdges.begin(); i != inputEdges.end(); ++i ) {
_NodeBasedEdge edge;
TarjanEdge edge;
if(!i->isForward()) {
edge.source = i->target();
edge.target = i->source();
@ -168,21 +173,28 @@ public:
edge.data.type = i->type();
edge.data.isAccessRestricted = i->isAccessRestricted();
edge.data.edgeBasedNodeID = edges.size();
edge.data.reversedEdge = false;
edges.push_back( edge );
if( edge.data.backward ) {
std::swap( edge.source, edge.target );
edge.data.forward = i->isBackward();
edge.data.backward = i->isForward();
edge.data.edgeBasedNodeID = edges.size();
edge.data.reversedEdge = true;
edges.push_back( edge );
}
}
std::vector<NodeBasedEdge>().swap(inputEdges);
std::sort( edges.begin(), edges.end() );
_nodeBasedGraph = boost::make_shared<_NodeBasedDynamicGraph>( nodes, edges );
_nodeBasedGraph = boost::make_shared<TarjanDynamicGraph>( nodes, edges );
}
void Run() {
//remove files from previous run if exist
DeleteFileIfExists("component.dbf");
DeleteFileIfExists("component.shx");
DeleteFileIfExists("component.shp");
Percent p(_nodeBasedGraph->GetNumberOfNodes());
const char *pszDriverName = "ESRI Shapefile";
@ -247,8 +259,8 @@ public:
// INFO("pushing " << v << " onto tarjan stack, idx[" << v << "]=" << tarjanNodes[v].index << ", lowlink["<< v << "]=" << tarjanNodes[v].lowlink);
//Traverse outgoing edges
for(_NodeBasedDynamicGraph::EdgeIterator e2 = _nodeBasedGraph->BeginEdges(v); e2 < _nodeBasedGraph->EndEdges(v); ++e2) {
_NodeBasedDynamicGraph::NodeIterator vprime = _nodeBasedGraph->GetTarget(e2);
for(TarjanDynamicGraph::EdgeIterator e2 = _nodeBasedGraph->BeginEdges(v); e2 < _nodeBasedGraph->EndEdges(v); ++e2) {
TarjanDynamicGraph::NodeIterator vprime = _nodeBasedGraph->GetTarget(e2);
// INFO("traversing edge (" << v << "," << vprime << ")");
if(UINT_MAX == tarjanNodes[vprime].index) {
@ -306,16 +318,28 @@ public:
++singleCounter;
}
INFO("identified " << singleCounter << " SCCs of size 1");
uint64_t total_network_distance = 0;
p.reinit(_nodeBasedGraph->GetNumberOfNodes());
for(_NodeBasedDynamicGraph::NodeIterator u = 0; u < _nodeBasedGraph->GetNumberOfNodes(); ++u ) {
for(_NodeBasedDynamicGraph::EdgeIterator e1 = _nodeBasedGraph->BeginEdges(u); e1 < _nodeBasedGraph->EndEdges(u); ++e1) {
_NodeBasedDynamicGraph::NodeIterator v = _nodeBasedGraph->GetTarget(e1);
for(TarjanDynamicGraph::NodeIterator u = 0; u < _nodeBasedGraph->GetNumberOfNodes(); ++u ) {
p.printIncrement();
for(TarjanDynamicGraph::EdgeIterator e1 = _nodeBasedGraph->BeginEdges(u); e1 < _nodeBasedGraph->EndEdges(u); ++e1) {
if(_nodeBasedGraph->GetEdgeData(e1).reversedEdge) {
continue;
}
TarjanDynamicGraph::NodeIterator v = _nodeBasedGraph->GetTarget(e1);
total_network_distance += 100*ApproximateDistance(
inputNodeInfoList[u].lat,
inputNodeInfoList[u].lon,
inputNodeInfoList[v].lat,
inputNodeInfoList[v].lon
);
if(_nodeBasedGraph->GetEdgeData(e1).type != SHRT_MAX) {
assert(e1 != UINT_MAX);
assert(u != UINT_MAX);
assert(v != UINT_MAX);
//edges that end on bollard nodes may actually be in two distinct components
if(std::min(vectorOfComponentSizes[componentsIndex[u]], vectorOfComponentSizes[componentsIndex[v]]) < 10) {
@ -323,7 +347,6 @@ public:
OGRLineString lineString;
lineString.addPoint(inputNodeInfoList[u].lon/100000., inputNodeInfoList[u].lat/100000.);
lineString.addPoint(inputNodeInfoList[v].lon/100000., inputNodeInfoList[v].lat/100000.);
OGRFeature *poFeature;
poFeature = OGRFeature::CreateFeature( poLayer->GetLayerDefn() );
poFeature->SetGeometry( &lineString );
@ -339,7 +362,7 @@ public:
OGRDataSource::DestroyDataSource( poDS );
std::vector<NodeID>().swap(vectorOfComponentSizes);
std::vector<NodeID>().swap(componentsIndex);
INFO("total network distance: " << total_network_distance/100/1000. << " km");
}
private:
unsigned CheckForEmanatingIsOnlyTurn(const NodeID u, const NodeID v) const {
@ -368,6 +391,12 @@ private:
}
return false;
}
void DeleteFileIfExists(const std::string file_name) const {
if (boost::filesystem::exists(file_name) ) {
boost::filesystem::remove(file_name);
}
}
};
#endif /* STRONGLYCONNECTEDCOMPONENTS_H_ */

View File

@ -21,21 +21,27 @@ file(GLOB PrepareGlob Contractor/*.cpp)
set(PrepareSources createHierarchy.cpp ${PrepareGlob})
add_executable(osrm-prepare ${PrepareSources})
file(GLOB RoutedGlob Server/DataStructures/*.cpp Descriptors/*.cpp DataStructures/SearchEngine*.cpp)
set(RoutedSources routed.cpp ${RoutedGlob})
add_executable(osrm-routed ${RoutedSources})
add_executable(osrm-routed routed.cpp)
set_target_properties(osrm-routed PROPERTIES COMPILE_FLAGS -DROUTED)
file(GLOB DescriptorGlob Descriptors/*.cpp)
file(GLOB LibOSRMGlob Library/*.cpp)
file(GLOB SearchEngineSource DataStructures/SearchEngine*.cpp)
file(GLOB ServerStructureGlob Server/DataStructures/*.cpp)
set(OSRMSources ${LibOSRMGlob} ${DescriptorGlob} ${SearchEngineSource} ${ServerStructureGlob})
add_library(OSRM SHARED ${OSRMSources})
# Check the release mode
if(NOT CMAKE_BUILD_TYPE MATCHES Debug)
set(CMAKE_BUILD_TYPE Release)
endif(NOT CMAKE_BUILD_TYPE MATCHES Debug)
endif(NOT CMAKE_BUILD_TYPE MATCHES Debug)
if(CMAKE_BUILD_TYPE MATCHES Debug)
message(STATUS "Configuring OSRM in debug mode")
endif(CMAKE_BUILD_TYPE MATCHES Debug)
endif(CMAKE_BUILD_TYPE MATCHES Debug)
if(CMAKE_BUILD_TYPE MATCHES Release)
message(STATUS "Configuring OSRM in release mode")
endif(CMAKE_BUILD_TYPE MATCHES Release)
endif(CMAKE_BUILD_TYPE MATCHES Release)
#Configuring compilers
if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang")
@ -44,7 +50,7 @@ if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang")
message(STATUS "OpenMP parallelization not available using clang++")
elseif ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU")
# using GCC
set(CMAKE_CXX_FLAGS "-Wall -fopenmp -pedantic")
set(CMAKE_CXX_FLAGS "-Wall -fopenmp -pedantic")
elseif ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Intel")
# using Intel C++
set(CMAKE_CXX_FLAGS "-static-intel -wd10237 -Wall -openmp -ipo")
@ -64,9 +70,11 @@ if (NOT Boost_FOUND)
message(FATAL_ERROR "Fatal error: Boost (version >= 1.44.0) required.\n")
endif (NOT Boost_FOUND)
include_directories(${Boost_INCLUDE_DIRS})
target_link_libraries( OSRM ${Boost_LIBRARIES})
target_link_libraries( osrm-extract ${Boost_LIBRARIES} )
target_link_libraries( osrm-prepare ${Boost_LIBRARIES} )
target_link_libraries( osrm-routed ${Boost_LIBRARIES} )
target_link_libraries( osrm-routed ${Boost_LIBRARIES} OSRM)
find_package ( BZip2 REQUIRED )
include_directories(${BZIP_INCLUDE_DIRS})
@ -79,13 +87,13 @@ target_link_libraries (osrm-routed ${ZLIB_LIBRARY})
find_package( Threads REQUIRED )
target_link_libraries (osrm-extract ${Threads_LIBRARY})
find_package( LuaJIT )
find_package( LuaJIT )
IF( LUAJIT_INCLUDE_DIR AND LUAJIT_LIBRARIES )
include_directories(${LUAJIT_INCLUDE_DIR})
target_link_libraries( osrm-extract ${LUAJIT_LIBRARIES} )
target_link_libraries( osrm-prepare ${LUAJIT_LIBRARIES} )
ELSE( LUAJIT_INCLUDE_DIR )
find_package( Lua51 REQUIRED AND LUAJIT_LIBRARIES )
find_package( Lua51 REQUIRED AND LUAJIT_LIBRARIES )
include_directories(${LUA_INCLUDE_DIR})
target_link_libraries( osrm-extract ${LUA_LIBRARY} )
target_link_libraries( osrm-prepare ${LUA_LIBRARY} )
@ -124,4 +132,6 @@ if(WITH_TOOLS)
target_link_libraries( osrm-components ${GDAL_LIBRARIES} )
target_link_libraries( osrm-components ${Boost_LIBRARIES} )
endif(GDAL_FOUND)
add_executable ( osrm-cli Tools/simpleclient.cpp)
target_link_libraries( osrm-cli ${Boost_LIBRARIES} OSRM)
endif(WITH_TOOLS)

View File

@ -474,7 +474,7 @@ public:
newEdge.data.id = data.id;
}
BOOST_ASSERT_MSG(
newEdge.data.id <= INT_MAX, //2^31
newEdge.data.id != INT_MAX, //2^31
"edge id invalid"
);
newEdge.data.forward = data.forward;

View File

@ -56,6 +56,17 @@
class EdgeBasedGraphFactory : boost::noncopyable {
public:
struct EdgeBasedNode {
EdgeBasedNode() :
id(INT_MAX),
lat1(INT_MAX),
lat2(INT_MAX),
lon1(INT_MAX),
lon2(INT_MAX >> 1),
belongsToTinyComponent(false),
nameID(UINT_MAX),
weight(UINT_MAX >> 1),
ignoreInGrid(false)
{ }
bool operator<(const EdgeBasedNode & other) const {
return other.id < id;
}

View File

@ -18,8 +18,6 @@
or see http://www.gnu.org/licenses/agpl.txt.
*/
#include <boost/foreach.hpp>
#include "TemporaryStorage.h"
TemporaryStorage::TemporaryStorage() {

View File

@ -24,6 +24,7 @@
#include <vector>
#include <fstream>
#include <boost/foreach.hpp>
#include <boost/filesystem.hpp>
#include <boost/filesystem/fstream.hpp>
#include <boost/shared_ptr.hpp>

View File

@ -23,13 +23,15 @@ or see http://www.gnu.org/licenses/agpl.txt.
//Not compatible with non contiguous node ids
#include <cassert>
#include <limits>
#include <vector>
#include <algorithm>
#include <map>
#include <boost/unordered_map.hpp>
#include <cassert>
#include <algorithm>
#include <limits>
#include <map>
#include <vector>
template< typename NodeID, typename Key >
class ArrayStorage {
public:
@ -184,8 +186,8 @@ public:
void DecreaseKey( NodeID node, Weight weight ) {
assert( UINT_MAX != node );
const Key index = nodeIndex[node];
Key key = insertedNodes[index].key;
const Key & index = nodeIndex[node];
Key & key = insertedNodes[index].key;
assert ( key >= 0 );
insertedNodes[index].weight = weight;

View File

@ -21,6 +21,8 @@ or see http://www.gnu.org/licenses/agpl.txt.
#ifndef COORDINATE_H_
#define COORDINATE_H_
#include "../Util/StringUtil.h"
#include <cassert>
#include <cmath>
#include <climits>
@ -31,7 +33,8 @@ struct _Coordinate {
int lat;
int lon;
_Coordinate () : lat(INT_MIN), lon(INT_MIN) {}
_Coordinate (int t, int n) : lat(t) , lon(n) {}
explicit _Coordinate (int t, int n) : lat(t) , lon(n) {}
void Reset() {
lat = INT_MIN;
lon = INT_MIN;
@ -87,7 +90,7 @@ inline double ApproximateDistance(const _Coordinate &c1, const _Coordinate &c2)
return ApproximateDistance( c1.lat, c1.lon, c2.lat, c2.lon );
}
inline double ApproximateDistanceByEuclid(const _Coordinate &c1, const _Coordinate &c2) {
inline double ApproximateEuclideanDistance(const _Coordinate &c1, const _Coordinate &c2) {
assert(c1.lat != INT_MIN);
assert(c1.lon != INT_MIN);
assert(c2.lat != INT_MIN);
@ -105,4 +108,30 @@ inline double ApproximateDistanceByEuclid(const _Coordinate &c1, const _Coordina
return d;
}
static inline void convertInternalLatLonToString(const int value, std::string & output) {
char buffer[100];
buffer[10] = 0; // Nullterminierung
char* string = printInt< 10, 5 >( buffer, value );
output = string;
}
static inline void convertInternalCoordinateToString(const _Coordinate & coord, std::string & output) {
std::string tmp;
convertInternalLatLonToString(coord.lon, tmp);
output = tmp;
output += ",";
convertInternalLatLonToString(coord.lat, tmp);
output += tmp;
output += " ";
}
static inline void convertInternalReversedCoordinateToString(const _Coordinate & coord, std::string & output) {
std::string tmp;
convertInternalLatLonToString(coord.lat, tmp);
output = tmp;
output += ",";
convertInternalLatLonToString(coord.lon, tmp);
output += tmp;
output += " ";
}
#endif /* COORDINATE_H_ */

View File

@ -1,82 +0,0 @@
/*
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_
#include "Coordinate.h"
struct _GridEdge {
_GridEdge(NodeID n, NodeID na, int w, _Coordinate sc, _Coordinate tc, bool bttc) : edgeBasedNode(n), nameID(na), weight(w), startCoord(sc), targetCoord(tc), belongsToTinyComponent(bttc) {}
_GridEdge() : edgeBasedNode(UINT_MAX), nameID(UINT_MAX), weight(INT_MAX), belongsToTinyComponent(false) {}
NodeID edgeBasedNode;
NodeID nameID;
int weight;
_Coordinate startCoord;
_Coordinate targetCoord;
bool belongsToTinyComponent;
bool operator< ( const _GridEdge& right) const {
return edgeBasedNode < right.edgeBasedNode;
}
bool operator== ( const _GridEdge& right) const {
return edgeBasedNode == right.edgeBasedNode;
}
};
struct GridEntry {
GridEntry() : fileIndex(UINT_MAX), ramIndex(UINT_MAX){}
GridEntry(_GridEdge e, unsigned f, unsigned r) : edge(e), fileIndex(f), ramIndex(r) {}
_GridEdge edge;
unsigned fileIndex;
unsigned ramIndex;
bool operator< ( const GridEntry& right ) const {
return (edge.edgeBasedNode < right.edge.edgeBasedNode);
}
bool operator==( const GridEntry& right ) const {
return right.edge.edgeBasedNode == edge.edgeBasedNode;
}
};
struct CompareGridEdgeDataByFileIndex {
bool operator () (const GridEntry & a, const GridEntry & b) const {
return a.fileIndex < b.fileIndex;
}
};
struct CompareGridEdgeDataByRamIndex {
typedef GridEntry value_type;
bool operator () (const GridEntry & a, const GridEntry & b) const {
return a.ramIndex < b.ramIndex;
}
value_type max_value() {
GridEntry e;
e.ramIndex = (1024*1024) - 1;
return e;
}
value_type min_value() {
GridEntry e;
e.ramIndex = 0;
return e;
}
};
#endif /* GRIDEDGE_H_ */

View File

@ -1,602 +0,0 @@
/*
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 <cassert>
#include <cfloat>
#include <cmath>
#include <cstring>
#include <algorithm>
#include <fstream>
#include <limits>
#include <vector>
#ifndef ROUTED
#include <stxxl.h>
#endif
#ifdef _WIN32
#include <math.h>
#endif
#include <boost/thread.hpp>
#include <boost/foreach.hpp>
#include <boost/unordered_map.hpp>
#include "DeallocatingVector.h"
#include "GridEdge.h"
#include "Percent.h"
#include "PhantomNodes.h"
#include "MercatorUtil.h"
#include "StaticGraph.h"
#include "TimingUtil.h"
#include "../Algorithms/Bresenham.h"
namespace NNGrid{
static boost::thread_specific_ptr<std::ifstream> localStream;
template<bool WriteAccess = false>
class NNGrid {
public:
NNGrid() /*: cellCache(500), fileCache(500)*/ {
ramIndexTable.resize((1024*1024), std::numeric_limits<uint64_t>::max());
}
NNGrid(const char* rif, const char* _i) {
if(WriteAccess) {
ERR("Not available in Write mode");
}
iif = std::string(_i);
ramIndexTable.resize((1024*1024), std::numeric_limits<uint64_t>::max());
ramInFile.open(rif, std::ios::in | std::ios::binary);
if(!ramInFile) { ERR(rif << " not found"); }
}
~NNGrid() {
if(ramInFile.is_open()) ramInFile.close();
#ifndef ROUTED
if (WriteAccess) {
entries.clear();
}
#endif
if(localStream.get() && localStream->is_open()) {
localStream->close();
}
}
void OpenIndexFiles() {
assert(ramInFile.is_open());
ramInFile.read(static_cast<char*>(static_cast<void*>(&ramIndexTable[0]) ), sizeof(uint64_t)*1024*1024);
ramInFile.close();
}
#ifndef ROUTED
template<typename EdgeT>
inline void ConstructGrid(DeallocatingVector<EdgeT> & edgeList, const char * ramIndexOut, const char * fileIndexOut) {
//TODO: Implement this using STXXL-Streams
Percent p(edgeList.size());
BOOST_FOREACH(EdgeT & edge, edgeList) {
p.printIncrement();
if(edge.ignoreInGrid)
continue;
int slat = 100000*lat2y(edge.lat1/100000.);
int slon = edge.lon1;
int tlat = 100000*lat2y(edge.lat2/100000.);
int tlon = edge.lon2;
AddEdge( _GridEdge( edge.id, edge.nameID, edge.weight, _Coordinate(slat, slon), _Coordinate(tlat, tlon), edge.belongsToTinyComponent ) );
}
if( 0 == entries.size() ) {
ERR("No viable edges for nearest neighbor index. Aborting");
}
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);
//sort entries
stxxl::sort(entries.begin(), entries.end(), CompareGridEdgeDataByRamIndex(), 1024*1024*1024);
INFO("finished sorting after " << (get_timestamp() - timestamp) << "s");
std::vector<GridEntry> entriesInFileWithRAMSameIndex;
unsigned indexInRamTable = entries.begin()->ramIndex;
uint64_t lastPositionInIndexFile = 0;
std::cout << "writing data ..." << std::flush;
p.reinit(entries.size());
boost::unordered_map< unsigned, unsigned > cellMap(1024);
BOOST_FOREACH(GridEntry & gridEntry, entries) {
p.printIncrement();
if(gridEntry.ramIndex != indexInRamTable) {
cellMap.clear();
BuildCellIndexToFileIndexMap(indexInRamTable, cellMap);
unsigned numberOfBytesInCell = FillCell(entriesInFileWithRAMSameIndex, lastPositionInIndexFile, cellMap);
ramIndexTable[indexInRamTable] = lastPositionInIndexFile;
lastPositionInIndexFile += numberOfBytesInCell;
entriesInFileWithRAMSameIndex.clear();
indexInRamTable = gridEntry.ramIndex;
}
entriesInFileWithRAMSameIndex.push_back(gridEntry);
}
cellMap.clear();
BuildCellIndexToFileIndexMap(indexInRamTable, cellMap);
/*unsigned numberOfBytesInCell = */FillCell(entriesInFileWithRAMSameIndex, lastPositionInIndexFile, cellMap);
ramIndexTable[indexInRamTable] = lastPositionInIndexFile;
entriesInFileWithRAMSameIndex.clear();
std::vector<GridEntry>().swap(entriesInFileWithRAMSameIndex);
assert(entriesInFileWithRAMSameIndex.size() == 0);
//close index file
indexOutFile.close();
//Serialize RAM Index
std::ofstream ramFile(ramIndexOut, std::ios::out | std::ios::binary | std::ios::trunc);
//write 4 MB of index Table in RAM
ramFile.write((char *)&ramIndexTable[0], sizeof(uint64_t)*1024*1024 );
//close ram index file
ramFile.close();
}
#endif
inline bool CoordinatesAreEquivalent(const _Coordinate & a, const _Coordinate & b, const _Coordinate & c, const _Coordinate & d) const {
return (a == b && c == d) || (a == c && b == d) || (a == d && b == c);
}
bool FindPhantomNodeForCoordinate( const _Coordinate & location, PhantomNode & resultNode, const unsigned zoomLevel) {
bool ignoreTinyComponents = (zoomLevel <= 14);
// INFO("Coordinate: " << location << ", zoomLevel: " << zoomLevel << ", ignoring tinyComponentents: " << (ignoreTinyComponents ? "yes" : "no"));
// double time1 = get_timestamp();
bool foundNode = false;
const _Coordinate startCoord(100000*(lat2y(static_cast<double>(location.lat)/100000.)), location.lon);
/** search for point on edge close to source */
const unsigned fileIndex = GetFileIndexForLatLon(startCoord.lat, startCoord.lon);
std::vector<_GridEdge> candidates;
const int lowerBoundForLoop = (fileIndex < 32768 ? 0 : -32768);
for(int j = lowerBoundForLoop; (j < (32768+1)) && (fileIndex != UINT_MAX); j+=32768) {
for(int i = -1; i < 2; ++i){
// unsigned oldSize = candidates.size();
GetContentsOfFileBucketEnumerated(fileIndex+i+j, candidates);
// INFO("Getting fileIndex=" << fileIndex+i+j << " with " << candidates.size() - oldSize << " candidates");
}
}
// INFO("looked up " << candidates.size());
_GridEdge smallestEdge;
_Coordinate tmp, edgeStartCoord, edgeEndCoord;
double dist = std::numeric_limits<double>::max();
double r, tmpDist;
BOOST_FOREACH(const _GridEdge & candidate, candidates) {
if(candidate.belongsToTinyComponent && ignoreTinyComponents)
continue;
r = 0.;
tmpDist = ComputeDistance(startCoord, candidate.startCoord, candidate.targetCoord, tmp, &r);
// INFO("dist " << startCoord << "->[" << candidate.startCoord << "-" << candidate.targetCoord << "]=" << tmpDist );
// INFO("Looking at edge " << candidate.edgeBasedNode << " at distance " << tmpDist);
if(tmpDist < dist && !DoubleEpsilonCompare(dist, tmpDist)) {
// INFO("a) " << candidate.edgeBasedNode << ", dist: " << tmpDist << ", tinyCC: " << (candidate.belongsToTinyComponent ? "yes" : "no"));
dist = tmpDist;
resultNode.edgeBasedNode = candidate.edgeBasedNode;
resultNode.nodeBasedEdgeNameID = candidate.nameID;
resultNode.weight1 = candidate.weight;
resultNode.weight2 = INT_MAX;
resultNode.location.lat = tmp.lat;
resultNode.location.lon = tmp.lon;
edgeStartCoord = candidate.startCoord;
edgeEndCoord = candidate.targetCoord;
foundNode = true;
smallestEdge = candidate;
//} else if(tmpDist < dist) {
//INFO("a) ignored " << candidate.edgeBasedNode << " at distance " << std::fabs(dist - tmpDist));
} else if(DoubleEpsilonCompare(dist, tmpDist) && 1 == std::abs(static_cast<int>(candidate.edgeBasedNode)-static_cast<int>(resultNode.edgeBasedNode) ) && CoordinatesAreEquivalent(edgeStartCoord, candidate.startCoord, edgeEndCoord, candidate.targetCoord)) {
resultNode.edgeBasedNode = std::min(candidate.edgeBasedNode, resultNode.edgeBasedNode);
resultNode.weight2 = candidate.weight;
//INFO("b) " << candidate.edgeBasedNode << ", dist: " << tmpDist);
}
}
// INFO("startcoord: " << smallestEdge.startCoord << ", tgtcoord" << smallestEdge.targetCoord << "result: " << newEndpoint);
// INFO("length of old edge: " << ApproximateDistance(smallestEdge.startCoord, smallestEdge.targetCoord));
// INFO("Length of new edge: " << ApproximateDistance(smallestEdge.startCoord, newEndpoint));
// assert(!resultNode.isBidirected() || (resultNode.weight1 == resultNode.weight2));
// if(resultNode.weight1 != resultNode.weight2) {
// INFO("-> Weight1: " << resultNode.weight1 << ", weight2: " << resultNode.weight2);
// INFO("-> node: " << resultNode.edgeBasedNode << ", bidir: " << (resultNode.isBidirected() ? "yes" : "no"));
// }
// INFO("startCoord: " << smallestEdge.startCoord << "; targetCoord: " << smallestEdge.targetCoord << "; newEndpoint: " << resultNode.location);
const double ratio = (foundNode ? std::min(1., ApproximateDistance(smallestEdge.startCoord, resultNode.location)/ApproximateDistance(smallestEdge.startCoord, smallestEdge.targetCoord)) : 0);
resultNode.location.lat = round(100000.*(y2lat(static_cast<double>(resultNode.location.lat)/100000.)));
// INFO("Length of vector: " << ApproximateDistance(smallestEdge.startCoord, resultNode.location)/ApproximateDistance(smallestEdge.startCoord, smallestEdge.targetCoord));
//Hack to fix rounding errors and wandering via nodes.
if(std::abs(location.lon - resultNode.location.lon) == 1)
resultNode.location.lon = location.lon;
if(std::abs(location.lat - resultNode.location.lat) == 1)
resultNode.location.lat = location.lat;
resultNode.weight1 *= ratio;
if(INT_MAX != resultNode.weight2) {
resultNode.weight2 *= (1.-ratio);
}
resultNode.ratio = ratio;
// INFO("start: " << edgeStartCoord << ", end: " << edgeEndCoord);
// INFO("selected node: " << resultNode.edgeBasedNode << ", bidirected: " << (resultNode.isBidirected() ? "yes" : "no"));
// INFO("New weight1: " << resultNode.weight1 << ", new weight2: " << resultNode.weight2 << ", ratio: " << ratio);
// INFO("distance to input coordinate: " << ApproximateDistance(location, resultNode.location) << "\n--");
// double time2 = get_timestamp();
// INFO("NN-Lookup in " << 1000*(time2-time1) << "ms");
return foundNode;
}
bool FindRoutingStarts(const _Coordinate& start, const _Coordinate& target, PhantomNodes & routingStarts, unsigned zoomLevel) {
routingStarts.Reset();
return (FindPhantomNodeForCoordinate( start, routingStarts.startPhantom, zoomLevel) &&
FindPhantomNodeForCoordinate( target, routingStarts.targetPhantom, zoomLevel) );
}
bool FindNearestCoordinateOnEdgeInNodeBasedGraph(const _Coordinate& inputCoordinate, _Coordinate& outputCoordinate, unsigned zoomLevel = 18) {
PhantomNode resultNode;
bool foundNode = FindPhantomNodeForCoordinate(inputCoordinate, resultNode, zoomLevel);
outputCoordinate = resultNode.location;
return foundNode;
}
void FindNearestPointOnEdge(const _Coordinate& inputCoordinate, _Coordinate& outputCoordinate) {
_Coordinate startCoord(100000*(lat2y(static_cast<double>(inputCoordinate.lat)/100000.)), inputCoordinate.lon);
unsigned fileIndex = GetFileIndexForLatLon(startCoord.lat, startCoord.lon);
std::vector<_GridEdge> candidates;
boost::unordered_map< unsigned, unsigned > cellMap;
for(int j = -32768; j < (32768+1); j+=32768) {
for(int i = -1; i < 2; ++i) {
GetContentsOfFileBucket(fileIndex+i+j, candidates, cellMap);
}
}
_Coordinate tmp;
double dist = (std::numeric_limits<double>::max)();
BOOST_FOREACH(const _GridEdge & candidate, candidates) {
double r = 0.;
double tmpDist = ComputeDistance(startCoord, candidate.startCoord, candidate.targetCoord, tmp, &r);
if(tmpDist < dist) {
dist = tmpDist;
outputCoordinate.lat = round(100000*(y2lat(static_cast<double>(tmp.lat)/100000.)));
outputCoordinate.lon = tmp.lon;
}
}
}
private:
inline unsigned GetCellIndexFromRAMAndFileIndex(const unsigned ramIndex, const unsigned fileIndex) const {
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) {
const unsigned localFileIndex = lineBase + i * 32768 + columnBase + j;
if(localFileIndex == fileIndex) {
unsigned cellIndex = i * 32 + j;
return cellIndex;
}
}
}
return UINT_MAX;
}
inline void BuildCellIndexToFileIndexMap(const unsigned ramIndex, boost::unordered_map<unsigned, unsigned >& cellMap){
unsigned lineBase = ramIndex/1024;
lineBase = lineBase*32*32768;
unsigned columnBase = ramIndex%1024;
columnBase=columnBase*32;
std::vector<std::pair<unsigned, unsigned> >insertionVector(1024);
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;
insertionVector[i * 32 + j] = std::make_pair(fileIndex, cellIndex);
}
}
cellMap.insert(insertionVector.begin(), insertionVector.end());
}
inline bool DoubleEpsilonCompare(const double d1, const double d2) const {
return (std::fabs(d1 - d2) < FLT_EPSILON);
}
#ifndef ROUTED
inline unsigned FillCell(std::vector<GridEntry>& entriesWithSameRAMIndex, const uint64_t fileOffset, boost::unordered_map< unsigned, unsigned > & cellMap ) {
std::vector<char> tmpBuffer(32*32*4096,0);
uint64_t indexIntoTmpBuffer = 0;
unsigned numberOfWrittenBytes = 0;
assert(indexOutFile.is_open());
std::vector<uint64_t> cellIndex(32*32,std::numeric_limits<uint64_t>::max());
for(unsigned i = 0; i < entriesWithSameRAMIndex.size() -1; ++i) {
assert(entriesWithSameRAMIndex[i].ramIndex== entriesWithSameRAMIndex[i+1].ramIndex);
}
//sort & unique
std::sort(entriesWithSameRAMIndex.begin(), entriesWithSameRAMIndex.end(), CompareGridEdgeDataByFileIndex());
// entriesWithSameRAMIndex.erase(std::unique(entriesWithSameRAMIndex.begin(), entriesWithSameRAMIndex.end()), entriesWithSameRAMIndex.end());
//traverse each file bucket and write its contents to disk
std::vector<GridEntry> entriesWithSameFileIndex;
unsigned fileIndex = entriesWithSameRAMIndex.begin()->fileIndex;
BOOST_FOREACH(GridEntry & gridEntry, entriesWithSameRAMIndex) {
assert(cellMap.find(gridEntry.fileIndex) != cellMap.end() ); //asserting that file index belongs to cell index
if(gridEntry.fileIndex != fileIndex) {
// start in cellIndex vermerken
int localFileIndex = entriesWithSameFileIndex.begin()->fileIndex;
int localCellIndex = cellMap.find(localFileIndex)->second;
assert(cellMap.find(entriesWithSameFileIndex.begin()->fileIndex) != cellMap.end());
cellIndex[localCellIndex] = indexIntoTmpBuffer + fileOffset;
indexIntoTmpBuffer += FlushEntriesWithSameFileIndexToBuffer(entriesWithSameFileIndex, tmpBuffer, indexIntoTmpBuffer);
fileIndex = gridEntry.fileIndex;
}
entriesWithSameFileIndex.push_back(gridEntry);
}
assert(cellMap.find(entriesWithSameFileIndex.begin()->fileIndex) != cellMap.end());
int localFileIndex = entriesWithSameFileIndex.begin()->fileIndex;
int localCellIndex = cellMap.find(localFileIndex)->second;
cellIndex[localCellIndex] = indexIntoTmpBuffer + fileOffset;
indexIntoTmpBuffer += FlushEntriesWithSameFileIndexToBuffer(entriesWithSameFileIndex, tmpBuffer, indexIntoTmpBuffer);
assert(entriesWithSameFileIndex.size() == 0);
indexOutFile.write(static_cast<char*>(static_cast<void*>(&cellIndex[0])),32*32*sizeof(uint64_t));
numberOfWrittenBytes += 32*32*sizeof(uint64_t);
//write contents of tmpbuffer to disk
indexOutFile.write(&tmpBuffer[0], indexIntoTmpBuffer*sizeof(char));
numberOfWrittenBytes += indexIntoTmpBuffer*sizeof(char);
return numberOfWrittenBytes;
}
inline unsigned FlushEntriesWithSameFileIndexToBuffer( std::vector<GridEntry> &vectorWithSameFileIndex, std::vector<char> & tmpBuffer, const uint64_t index) const {
sort( vectorWithSameFileIndex.begin(), vectorWithSameFileIndex.end() );
vectorWithSameFileIndex.erase(unique(vectorWithSameFileIndex.begin(), vectorWithSameFileIndex.end()), vectorWithSameFileIndex.end());
const unsigned lengthOfBucket = vectorWithSameFileIndex.size();
tmpBuffer.resize(tmpBuffer.size()+(sizeof(_GridEdge)*lengthOfBucket) + sizeof(unsigned) );
unsigned counter = 0;
for(unsigned i = 0; i < vectorWithSameFileIndex.size()-1; ++i) {
assert( vectorWithSameFileIndex[i].fileIndex == vectorWithSameFileIndex[i+1].fileIndex );
assert( vectorWithSameFileIndex[i].ramIndex == vectorWithSameFileIndex[i+1].ramIndex );
}
//write length of bucket
memcpy((char*)&(tmpBuffer[index+counter]), (char*)&lengthOfBucket, sizeof(lengthOfBucket));
counter += sizeof(lengthOfBucket);
BOOST_FOREACH(const GridEntry & entry, vectorWithSameFileIndex) {
char * data = (char*)&(entry.edge);
memcpy(static_cast<char*>(static_cast<void*>(&(tmpBuffer[index+counter]) )), data, sizeof(entry.edge));
counter += sizeof(entry.edge);
}
//Freeing data
vectorWithSameFileIndex.clear();
return counter;
}
#endif
inline void GetContentsOfFileBucketEnumerated(const unsigned fileIndex, std::vector<_GridEdge>& result) const {
unsigned ramIndex = GetRAMIndexFromFileIndex(fileIndex);
uint64_t startIndexInFile = ramIndexTable[ramIndex];
if(startIndexInFile == std::numeric_limits<uint64_t>::max()) {
return;
}
unsigned enumeratedIndex = GetCellIndexFromRAMAndFileIndex(ramIndex, fileIndex);
if(!localStream.get() || !localStream->is_open()) {
localStream.reset(new std::ifstream(iif.c_str(), std::ios::in | std::ios::binary));
}
if(!localStream->good()) {
localStream->clear(std::ios::goodbit);
DEBUG("Resetting stale filestream");
}
//only read the single necessary cell index
localStream->seekg(startIndexInFile+(enumeratedIndex*sizeof(uint64_t)));
uint64_t fetchedIndex = 0;
localStream->read(static_cast<char*>( static_cast<void*>(&fetchedIndex)), sizeof(uint64_t));
if(fetchedIndex == std::numeric_limits<uint64_t>::max()) {
return;
}
const uint64_t position = fetchedIndex + 32*32*sizeof(uint64_t) ;
unsigned lengthOfBucket;
unsigned currentSizeOfResult = result.size();
localStream->seekg(position);
localStream->read(static_cast<char*>( static_cast<void*>(&(lengthOfBucket))), sizeof(unsigned));
result.resize(currentSizeOfResult+lengthOfBucket);
localStream->read(static_cast<char*>( static_cast<void*>(&result[currentSizeOfResult])), lengthOfBucket*sizeof(_GridEdge));
}
inline void GetContentsOfFileBucket(const unsigned fileIndex, std::vector<_GridEdge>& result, boost::unordered_map< unsigned, unsigned> & cellMap) {
unsigned ramIndex = GetRAMIndexFromFileIndex(fileIndex);
uint64_t startIndexInFile = ramIndexTable[ramIndex];
if(startIndexInFile == std::numeric_limits<uint64_t>::max()) {
return;
}
uint64_t cellIndex[32*32];
cellMap.clear();
BuildCellIndexToFileIndexMap(ramIndex, cellMap);
if(!localStream.get() || !localStream->is_open()) {
localStream.reset(new std::ifstream(iif.c_str(), std::ios::in | std::ios::binary));
}
if(!localStream->good()) {
localStream->clear(std::ios::goodbit);
DEBUG("Resetting stale filestream");
}
localStream->seekg(startIndexInFile);
localStream->read(static_cast<char*>(static_cast<void*>( cellIndex)), 32*32*sizeof(uint64_t));
assert(cellMap.find(fileIndex) != cellMap.end());
if(cellIndex[cellMap[fileIndex]] == std::numeric_limits<uint64_t>::max()) {
return;
}
const uint64_t position = cellIndex[cellMap[fileIndex]] + 32*32*sizeof(uint64_t) ;
unsigned lengthOfBucket;
unsigned currentSizeOfResult = result.size();
localStream->seekg(position);
localStream->read(static_cast<char*>(static_cast<void*>(&(lengthOfBucket))), sizeof(unsigned));
result.resize(currentSizeOfResult+lengthOfBucket);
localStream->read(static_cast<char*>(static_cast<void*>(&result[currentSizeOfResult])), lengthOfBucket*sizeof(_GridEdge));
}
#ifndef ROUTED
inline void AddEdge(const _GridEdge & edge) {
std::vector<BresenhamPixel> indexList;
GetListOfIndexesForEdgeAndGridSize(edge.startCoord, edge.targetCoord, indexList);
for(unsigned i = 0; i < indexList.size(); ++i) {
entries.push_back(GridEntry(edge, indexList[i].first, indexList[i].second));
}
}
#endif
inline double ComputeDistance(const _Coordinate& inputPoint, const _Coordinate& source, const _Coordinate& target, _Coordinate& nearest, double *r) {
// INFO("comparing point " << inputPoint << " to edge [" << source << "-" << target << "]");
const double x = static_cast<double>(inputPoint.lat);
const double y = static_cast<double>(inputPoint.lon);
const double a = static_cast<double>(source.lat);
const double b = static_cast<double>(source.lon);
const double c = static_cast<double>(target.lat);
const double d = static_cast<double>(target.lon);
double p,q,mX,nY;
// INFO("x=" << x << ", y=" << y << ", a=" << a << ", b=" << b << ", c=" << c << ", d=" << d);
if(fabs(a-c) > FLT_EPSILON){
const double m = (d-b)/(c-a); // slope
// Projection of (x,y) on line joining (a,b) and (c,d)
p = ((x + (m*y)) + (m*m*a - m*b))/(1. + m*m);
q = b + m*(p - a);
}
else{
p = c;
q = y;
}
nY = (d*p - c*q)/(a*d - b*c);
mX = (p - nY*a)/c;// These values are actually n/m+n and m/m+n , we neednot calculate the values of m an n as we are just interested in the ratio
// INFO("p=" << p << ", q=" << q << ", nY=" << nY << ", mX=" << mX);
if(std::isnan(mX)) {
*r = (target == inputPoint) ? 1. : 0.;
} else {
*r = mX;
}
// INFO("r=" << *r);
if(*r<=0.){
nearest.lat = source.lat;
nearest.lon = source.lon;
// INFO("a returning distance " << ((b - y)*(b - y) + (a - x)*(a - x)))
return ((b - y)*(b - y) + (a - x)*(a - x));
}
else if(*r >= 1.){
nearest.lat = target.lat;
nearest.lon = target.lon;
// INFO("b returning distance " << ((d - y)*(d - y) + (c - x)*(c - x)))
return ((d - y)*(d - y) + (c - x)*(c - x));
}
// point lies in between
nearest.lat = p;
nearest.lon = q;
// INFO("c returning distance " << (p-x)*(p-x) + (q-y)*(q-y))
return (p-x)*(p-x) + (q-y)*(q-y);
}
inline void GetListOfIndexesForEdgeAndGridSize(const _Coordinate& start, const _Coordinate& target, std::vector<BresenhamPixel> &indexList) const {
double lat1 = start.lat/100000.;
double lon1 = start.lon/100000.;
double x1 = ( lon1 + 180.0 ) / 360.0;
double y1 = ( lat1 + 180.0 ) / 360.0;
double lat2 = target.lat/100000.;
double lon2 = target.lon/100000.;
double x2 = ( lon2 + 180.0 ) / 360.0;
double y2 = ( lat2 + 180.0 ) / 360.0;
Bresenham(x1*32768, y1*32768, x2*32768, y2*32768, indexList);
BOOST_FOREACH(BresenhamPixel & pixel, indexList) {
int fileIndex = (pixel.second-1)*32768 + pixel.first;
int ramIndex = GetRAMIndexFromFileIndex(fileIndex);
pixel.first = fileIndex;
pixel.second = ramIndex;
}
}
inline unsigned GetFileIndexForLatLon(const int lt, const int ln) const {
double lat = lt/100000.;
double lon = ln/100000.;
double x = ( lon + 180.0 ) / 360.0;
double y = ( lat + 180.0 ) / 360.0;
if( x>1.0 || x < 0.)
return UINT_MAX;
if( y>1.0 || y < 0.)
return UINT_MAX;
unsigned line = (32768 * (32768-1))*y;
line = line - (line % 32768);
assert(line % 32768 == 0);
unsigned column = 32768.*x;
unsigned fileIndex = line+column;
return fileIndex;
}
inline unsigned GetRAMIndexFromFileIndex(const int fileIndex) const {
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;
}
const static uint64_t END_OF_BUCKET_DELIMITER = boost::integer_traits<uint64_t>::const_max;
std::ifstream ramInFile;
#ifndef ROUTED
std::ofstream indexOutFile;
stxxl::vector<GridEntry> entries;
#endif
std::vector<uint64_t> ramIndexTable; //8 MB for first level index in RAM
std::string iif;
// LRUCache<int,std::vector<unsigned> > cellCache;
// LRUCache<int,std::vector<_Edge> > fileCache;
};
}
typedef NNGrid::NNGrid<false> ReadOnlyGrid;
typedef NNGrid::NNGrid<true > WritableGrid;
#endif /* NNGRID_H_ */

View File

@ -21,12 +21,13 @@ or see http://www.gnu.org/licenses/agpl.txt.
#ifndef _NODE_COORDS_H
#define _NODE_COORDS_H
#include "../typedefs.h"
#include <cassert>
#include <cstddef>
#include <climits>
#include <limits>
#include "../typedefs.h"
#include <limits>
template<typename NodeT>
struct NodeCoords {

View File

@ -23,7 +23,6 @@ or see http://www.gnu.org/licenses/agpl.txt.
#include "NodeCoords.h"
#include "PhantomNodes.h"
#include "QueryEdge.h"
#include "StaticRTree.h"
#include "../Contractor/EdgeBasedGraphFactory.h"
#include "../typedefs.h"
@ -82,7 +81,10 @@ public:
OriginalEdgeData deserialized_originalEdgeData;
for(unsigned i = 0; i < numberOfOrigEdges; ++i) {
edgesInStream.read((char*)&(deserialized_originalEdgeData), sizeof(OriginalEdgeData));
edgesInStream.read(
(char*)&(deserialized_originalEdgeData),
sizeof(OriginalEdgeData)
);
origEdgeData_viaNode[i] = deserialized_originalEdgeData.viaNode;
origEdgeData_nameID[i] = deserialized_originalEdgeData.nameID;
origEdgeData_turnInstruction[i] = deserialized_originalEdgeData.turnInstruction;
@ -124,7 +126,10 @@ public:
const unsigned zoom_level = 18
) const {
PhantomNode resulting_phantom_node;
bool foundNode = FindPhantomNodeForCoordinate(input_coordinate, resulting_phantom_node, zoom_level);
bool foundNode = FindPhantomNodeForCoordinate(
input_coordinate,
resulting_phantom_node, zoom_level
);
result = resulting_phantom_node.location;
return foundNode;
}

View File

@ -21,9 +21,9 @@ or see http://www.gnu.org/licenses/agpl.txt.
#ifndef PERCENT_H
#define PERCENT_H
#include "../Util/OpenMPWrapper.h"
#include <iostream>
class Percent
{
public:

View File

@ -30,25 +30,43 @@ struct _Restriction {
NodeID fromNode;
NodeID toNode;
struct Bits { //mostly unused
Bits() : isOnly(false), unused1(false), unused2(false), unused3(false), unused4(false), unused5(false), unused6(false), unused7(false) {}
char isOnly:1;
char unused1:1;
char unused2:1;
char unused3:1;
char unused4:1;
char unused5:1;
char unused6:1;
char unused7:1;
Bits() :
isOnly(false),
unused1(false),
unused2(false),
unused3(false),
unused4(false),
unused5(false),
unused6(false),
unused7(false) {
}
bool isOnly:1;
bool unused1:1;
bool unused2:1;
bool unused3:1;
bool unused4:1;
bool unused5:1;
bool unused6:1;
bool unused7:1;
} flags;
_Restriction(NodeID vn) : viaNode(vn), fromNode(UINT_MAX), toNode(UINT_MAX) { }
_Restriction(bool isOnly = false) : viaNode(UINT_MAX), fromNode(UINT_MAX), toNode(UINT_MAX) {
_Restriction(NodeID vn) :
viaNode(vn),
fromNode(UINT_MAX),
toNode(UINT_MAX) {
}
_Restriction(const bool isOnly = false) :
viaNode(UINT_MAX),
fromNode(UINT_MAX),
toNode(UINT_MAX) {
flags.isOnly = isOnly;
}
};
inline bool CmpRestrictionByFrom ( _Restriction a, _Restriction b) { return (a.fromNode < b.fromNode); }
struct _RawRestrictionContainer {
_Restriction restriction;
EdgeID fromWay;
@ -66,7 +84,7 @@ struct _RawRestrictionContainer {
}
};
struct CmpRestrictionContainerByFrom: public std::binary_function<_RawRestrictionContainer, _RawRestrictionContainer, bool> {
struct CmpRestrictionContainerByFrom : public std::binary_function<_RawRestrictionContainer, _RawRestrictionContainer, bool> {
typedef _RawRestrictionContainer value_type;
bool operator () (const _RawRestrictionContainer & a, const _RawRestrictionContainer & b) const {
return a.fromWay < b.fromWay;
@ -92,6 +110,4 @@ struct CmpRestrictionContainerByTo: public std::binary_function<_RawRestrictionC
}
};
#endif /* RESTRICTION_H_ */

View File

@ -21,9 +21,10 @@ or see http://www.gnu.org/licenses/agpl.txt.
#ifndef SEGMENTINFORMATION_H_
#define SEGMENTINFORMATION_H_
#include <climits>
#include "TurnInstructions.h"
#include "../typedefs.h"
#include <climits>
struct SegmentInformation {
_Coordinate location;

View File

@ -21,11 +21,10 @@ or see http://www.gnu.org/licenses/agpl.txt.
#ifndef STATICGRAPH_H_INCLUDED
#define STATICGRAPH_H_INCLUDED
#include <vector>
#include <algorithm>
#include "../typedefs.h"
#include "ImportEdge.h"
#include <algorithm>
#include <vector>
template< typename EdgeDataT>
class StaticGraph {

View File

@ -215,8 +215,14 @@ private:
return lats_contained && lons_contained;
}
inline friend std::ostream & operator<< ( std::ostream & out, const RectangleInt2D & rect ) {
out << rect.min_lat/100000. << "," << rect.min_lon/100000. << " " << rect.max_lat/100000. << "," << rect.max_lon/100000.;
inline friend std::ostream & operator<< (
std::ostream & out,
const RectangleInt2D & rect
) {
out << rect.min_lat/100000. << ","
<< rect.min_lon/100000. << " "
<< rect.max_lat/100000. << ","
<< rect.max_lon/100000.;
return out;
}
};
@ -224,8 +230,11 @@ private:
typedef RectangleInt2D RectangleT;
struct WrappedInputElement {
explicit WrappedInputElement(const uint32_t _array_index, const uint64_t _hilbert_value) :
m_array_index(_array_index), m_hilbert_value(_hilbert_value) {}
explicit WrappedInputElement(
const uint32_t _array_index,
const uint64_t _hilbert_value
) : m_array_index(_array_index), m_hilbert_value(_hilbert_value) {}
WrappedInputElement() : m_array_index(UINT_MAX), m_hilbert_value(0) {}
uint32_t m_array_index;
@ -251,11 +260,13 @@ private:
};
struct QueryCandidate {
explicit QueryCandidate(const uint32_t n_id, const double dist) : node_id(n_id), min_dist(dist)/*, minmax_dist(DBL_MAX)*/ {}
QueryCandidate() : node_id(UINT_MAX), min_dist(DBL_MAX)/*, minmax_dist(DBL_MAX)*/ {}
explicit QueryCandidate(
const uint32_t n_id,
const double dist
) : node_id(n_id), min_dist(dist) {}
QueryCandidate() : node_id(UINT_MAX), min_dist(DBL_MAX) {}
uint32_t node_id;
double min_dist;
// double minmax_dist;
inline bool operator<(const QueryCandidate & other) const {
return min_dist < other.min_dist;
}
@ -266,24 +277,23 @@ private:
std::string m_leaf_node_filename;
public:
//Construct a pack R-Tree from the input-list with Kamel-Faloutsos algorithm [1]
explicit StaticRTree(std::vector<DataT> & input_data_vector, const char * tree_node_filename, const char * leaf_node_filename) :
m_leaf_node_filename(leaf_node_filename) {
m_element_count = input_data_vector.size();
//remove elements that are flagged to be ignored
// boost::remove_erase_if(input_data_vector, boost::bind(&DataT::isIgnored, _1 ));
//Construct a packed Hilbert-R-Tree with Kamel-Faloutsos algorithm [1]
explicit StaticRTree(
std::vector<DataT> & input_data_vector,
const char * tree_node_filename,
const char * leaf_node_filename
) :
m_element_count(input_data_vector.size()),
m_leaf_node_filename(leaf_node_filename)
{
INFO("constructing r-tree of " << m_element_count << " elements");
// INFO("sizeof(LeafNode)=" << sizeof(LeafNode));
// INFO("sizeof(TreeNode)=" << sizeof(TreeNode));
// INFO("sizeof(WrappedInputElement)=" << sizeof(WrappedInputElement));
double time1 = get_timestamp();
std::vector<WrappedInputElement> input_wrapper_vector(input_data_vector.size());
std::vector<WrappedInputElement> input_wrapper_vector(m_element_count);
//generate auxiliary vector of hilbert-values
#pragma omp parallel for schedule(guided)
for(uint64_t element_counter = 0; element_counter < m_element_count; ++element_counter) {
//INFO("ID: " << input_data_vector[element_counter].id);
input_wrapper_vector[element_counter].m_array_index = element_counter;
//Get Hilbert-Value for centroid in mercartor projection
DataT & current_element = input_data_vector[element_counter];
@ -294,15 +304,12 @@ public:
input_wrapper_vector[element_counter].m_hilbert_value = current_hilbert_value;
}
//INFO("finished wrapper setup");
//open leaf file
std::ofstream leaf_node_file(leaf_node_filename, std::ios::binary);
leaf_node_file.write((char*) &m_element_count, sizeof(uint64_t));
//sort the hilbert-value representatives
std::sort(input_wrapper_vector.begin(), input_wrapper_vector.end());
// INFO("finished sorting");
std::vector<TreeNode> tree_nodes_in_level;
//pack M elements into leaf node and write to leaf file
@ -313,19 +320,12 @@ public:
TreeNode current_node;
for(uint32_t current_element_index = 0; RTREE_LEAF_NODE_SIZE > current_element_index; ++current_element_index) {
if(m_element_count > (processed_objects_count + current_element_index)) {
// INFO("Checking element " << (processed_objects_count + current_element_index));
uint32_t index_of_next_object = input_wrapper_vector[processed_objects_count + current_element_index].m_array_index;
current_leaf.objects[current_element_index] = input_data_vector[index_of_next_object];
++current_leaf.object_count;
}
}
if(0 == processed_objects_count) {
for(uint32_t i = 0; i < current_leaf.object_count; ++i) {
//INFO("[" << i << "] id: " << current_leaf.objects[i].id << ", weight: " << current_leaf.objects[i].weight << ", " << current_leaf.objects[i].lat1/100000. << "," << current_leaf.objects[i].lon1/100000. << ";" << current_leaf.objects[i].lat2/100000. << "," << current_leaf.objects[i].lon2/100000.);
}
}
//generate tree node that resemble the objects in leaf and store it for next level
current_node.minimum_bounding_rectangle.InitializeMBRectangle(current_leaf.objects, current_leaf.object_count);
current_node.child_is_on_disk = true;
@ -337,20 +337,21 @@ public:
processed_objects_count += current_leaf.object_count;
}
// INFO("wrote " << processed_objects_count << " leaf objects");
//close leaf file
leaf_node_file.close();
uint32_t processing_level = 0;
while(1 < tree_nodes_in_level.size()) {
// INFO("processing " << (uint32_t)tree_nodes_in_level.size() << " tree nodes in level " << processing_level);
std::vector<TreeNode> tree_nodes_in_next_level;
uint32_t processed_tree_nodes_in_level = 0;
while(processed_tree_nodes_in_level < tree_nodes_in_level.size()) {
TreeNode parent_node;
//pack RTREE_BRANCHING_FACTOR elements into tree_nodes each
for(uint32_t current_child_node_index = 0; RTREE_BRANCHING_FACTOR > current_child_node_index; ++current_child_node_index) {
for(
uint32_t current_child_node_index = 0;
RTREE_BRANCHING_FACTOR > current_child_node_index;
++current_child_node_index
) {
if(processed_tree_nodes_in_level < tree_nodes_in_level.size()) {
TreeNode & current_child_node = tree_nodes_in_level[processed_tree_nodes_in_level];
//add tree node to parent entry
@ -364,15 +365,12 @@ public:
}
}
tree_nodes_in_next_level.push_back(parent_node);
// INFO("processed: " << processed_tree_nodes_in_level << ", generating " << (uint32_t)tree_nodes_in_next_level.size() << " parents");
}
tree_nodes_in_level.swap(tree_nodes_in_next_level);
++processing_level;
}
BOOST_ASSERT_MSG(1 == tree_nodes_in_level.size(), "tree broken, more than one root node");
//last remaining entry is the root node;
// INFO("root node has " << (uint32_t)tree_nodes_in_level[0].child_count << " children");
//store root node
//last remaining entry is the root node, store it
m_search_tree.push_back(tree_nodes_in_level[0]);
//reverse and renumber tree to have root at index 0
@ -396,27 +394,7 @@ public:
//close tree node file.
tree_node_file.close();
double time2 = get_timestamp();
// INFO("written " << processed_objects_count << " leafs in " << sizeof(LeafNode)*(1+(unsigned)std::ceil(processed_objects_count/RTREE_LEAF_NODE_SIZE) )+sizeof(uint64_t) << " bytes");
// INFO("written search tree of " << size_of_tree << " tree nodes in " << sizeof(TreeNode)*size_of_tree+sizeof(uint32_t) << " bytes");
INFO("finished r-tree construction in " << (time2-time1) << " seconds");
//todo: test queries
/* INFO("first MBR:" << m_search_tree[0].minimum_bounding_rectangle);
DataT result;
time1 = get_timestamp();
bool found_nearest = NearestNeighbor(_Coordinate(50.191085,8.466479), result);
time2 = get_timestamp();
INFO("found nearest element to (50.191085,8.466479): " << (found_nearest ? "yes" : "no") << " in " << (time2-time1) << "s at (" << result.lat1/100000. << "," << result.lon1/100000. << " " << result.lat2/100000. << "," << result.lon2/100000. << ")");
time1 = get_timestamp();
found_nearest = NearestNeighbor(_Coordinate(50.23979, 8.51882), result);
time2 = get_timestamp();
INFO("found nearest element to (50.23979, 8.51882): " << (found_nearest ? "yes" : "no") << " in " << (time2-time1) << "s at (" << result.lat1/100000. << "," << result.lon1/100000. << " " << result.lat2/100000. << "," << result.lon2/100000. << ")");
time1 = get_timestamp();
found_nearest = NearestNeighbor(_Coordinate(49.0316,2.6937), result);
time2 = get_timestamp();
INFO("found nearest element to (49.0316,2.6937): " << (found_nearest ? "yes" : "no") << " in " << (time2-time1) << "s at (" << result.lat1/100000. << "," << result.lon1/100000. << " " << result.lat2/100000. << "," << result.lon2/100000. << ")");
*/
}
//Read-only operation for queries
@ -557,11 +535,20 @@ public:
}
}
const double distance_to_edge =
ApproximateDistance (
_Coordinate(nearest_edge.lat1, nearest_edge.lon1),
result_phantom_node.location
);
const double length_of_edge =
ApproximateDistance(
_Coordinate(nearest_edge.lat1, nearest_edge.lon1),
_Coordinate(nearest_edge.lat2, nearest_edge.lon2)
);
const double ratio = (found_a_nearest_edge ?
std::min(1., ApproximateDistance(_Coordinate(nearest_edge.lat1, nearest_edge.lon1),
result_phantom_node.location)/ApproximateDistance(_Coordinate(nearest_edge.lat1, nearest_edge.lon1), _Coordinate(nearest_edge.lat2, nearest_edge.lon2))
) : 0
);
std::min(1., distance_to_edge/ length_of_edge ) : 0 );
result_phantom_node.weight1 *= ratio;
if(INT_MAX != result_phantom_node.weight2) {
result_phantom_node.weight2 *= (1.-ratio);
@ -576,8 +563,7 @@ public:
result_phantom_node.location.lat = input_coordinate.lat;
}
INFO("mindist: " << min_dist << ", io's: " << io_count << ", nodes: " << explored_tree_nodes_count << ", loc: " << result_phantom_node.location << ", ratio: " << ratio << ", id: " << result_phantom_node.edgeBasedNode);
INFO("bidirected: " << (result_phantom_node.isBidirected() ? "yes" : "no") );
INFO("mindist: " << min_distphantom_node.isBidirected() ? "yes" : "no") );
return found_a_nearest_edge;
}
@ -644,10 +630,6 @@ public:
&current_ratio
);
//INFO("[" << current_edge.id << "] (" << current_edge.lat1/100000. << "," << current_edge.lon1/100000. << ")==(" << current_edge.lat2/100000. << "," << current_edge.lon2/100000. << ") at distance " << current_perpendicular_distance << " min dist: " << min_dist
// << ", ratio " << current_ratio
// );
if(
current_perpendicular_distance < min_dist
&& !DoubleEpsilonCompare(
@ -737,94 +719,9 @@ public:
result_phantom_node.location.lat = input_coordinate.lat;
}
// INFO("start: (" << nearest_edge.lat1 << "," << nearest_edge.lon1 << "), end: (" << nearest_edge.lat2 << "," << nearest_edge.lon2 << ")" );
// INFO("mindist: " << min_dist << ", io's: " << io_count << ", nodes: " << explored_tree_nodes_count << ", loc: " << result_phantom_node.location << ", ratio: " << ratio << ", id: " << result_phantom_node.edgeBasedNode);
// INFO("weight1: " << result_phantom_node.weight1 << ", weight2: " << result_phantom_node.weight2);
// INFO("bidirected: " << (result_phantom_node.isBidirected() ? "yes" : "no") );
// INFO("NameID: " << result_phantom_node.nodeBasedEdgeNameID);
return found_a_nearest_edge;
}
/*
//Nearest-Neighbor query with the Roussopoulos et al. algorithm [2]
inline bool NearestNeighbor(const _Coordinate & input_coordinate, DataT & result_element) {
uint32_t io_count = 0;
uint32_t explored_tree_nodes_count = 0;
INFO("searching for coordinate " << input_coordinate);
double min_dist = DBL_MAX;
double min_max_dist = DBL_MAX;
bool found_return_value = false;
//initialize queue with root element
std::priority_queue<QueryCandidate> traversal_queue;
traversal_queue.push(QueryCandidate(0, m_search_tree[0].minimum_bounding_rectangle.GetMinDist(input_coordinate)));
BOOST_ASSERT_MSG(FLT_EPSILON > (0. - traversal_queue.top().min_dist), "Root element in NN Search has min dist != 0.");
while(!traversal_queue.empty()) {
const QueryCandidate current_query_node = traversal_queue.top(); traversal_queue.pop();
++explored_tree_nodes_count;
// INFO("popped node " << current_query_node.node_id << " at distance " << current_query_node.min_dist);
bool prune_downward = (current_query_node.min_dist >= min_max_dist);
bool prune_upward = (current_query_node.min_dist >= min_dist);
// INFO(" up prune: " << (prune_upward ? "y" : "n" ));
// INFO(" down prune: " << (prune_downward ? "y" : "n" ));
if( prune_downward || prune_upward ) { //downward pruning
// INFO(" pruned node " << current_query_node.node_id << " because " << current_query_node.min_dist << "<" << min_max_dist);
} else {
TreeNode & current_tree_node = m_search_tree[current_query_node.node_id];
if (current_tree_node.child_is_on_disk) {
// INFO(" Fetching child from disk for id: " << current_query_node.node_id);
LeafNode current_leaf_node;
LoadLeafFromDisk(current_tree_node.children[0], current_leaf_node);
++io_count;
double ratio = 0.;
_Coordinate nearest;
for(uint32_t i = 0; i < current_leaf_node.object_count; ++i) {
DataT & current_object = current_leaf_node.objects[i];
double current_perpendicular_distance = ComputePerpendicularDistance(
input_coordinate,
_Coordinate(current_object.lat1, current_object.lon1),
_Coordinate(current_object.lat2, current_object.lon2),
nearest,
&ratio
);
if(current_perpendicular_distance < min_dist && !DoubleEpsilonCompare(current_perpendicular_distance, min_dist)) { //found a new minimum
min_dist = current_perpendicular_distance;
result_element = current_object;
found_return_value = true;
}
}
} else {
//traverse children, prune if global mindist is smaller than local one
// INFO(" Checking " << current_tree_node.child_count << " children of node " << current_query_node.node_id);
for (uint32_t i = 0; i < current_tree_node.child_count; ++i) {
const int32_t child_id = current_tree_node.children[i];
TreeNode & child_tree_node = m_search_tree[child_id];
RectangleT & child_rectangle = child_tree_node.minimum_bounding_rectangle;
const double current_min_dist = child_rectangle.GetMinDist(input_coordinate);
const double current_min_max_dist = child_rectangle.GetMinMaxDist(input_coordinate);
if( current_min_max_dist < min_max_dist ) {
min_max_dist = current_min_max_dist;
}
if (current_min_dist > min_max_dist) {
continue;
}
if (current_min_dist > min_dist) { //upward pruning
continue;
}
// INFO(" pushing node " << child_id << " at distance " << current_min_dist);
traversal_queue.push(QueryCandidate(child_id, current_min_dist));
}
}
}
}
INFO("mindist: " << min_dist << ", io's: " << io_count << ", touched nodes: " << explored_tree_nodes_count);
return found_return_value;
}
*/
private:
inline void LoadLeafFromDisk(const uint32_t leaf_id, LeafNode& result_node) {
if(!thread_local_rtree_stream.get() || !thread_local_rtree_stream->is_open()) {

View File

@ -21,12 +21,12 @@ or see http://www.gnu.org/licenses/agpl.txt.
#ifndef XORFASTHASHSTORAGE_H_
#define XORFASTHASHSTORAGE_H_
#include "XORFastHash.h"
#include <climits>
#include <vector>
#include <bitset>
#include "XORFastHash.h"
template< typename NodeID, typename Key >
class XORFastHashStorage {
public:

View File

@ -21,19 +21,19 @@ or see http://www.gnu.org/licenses/agpl.txt.
#ifndef BASE_DESCRIPTOR_H_
#define BASE_DESCRIPTOR_H_
#include <cassert>
#include <cmath>
#include <cstdio>
#include <string>
#include <vector>
#include "../typedefs.h"
#include "../DataStructures/HashTable.h"
#include "../DataStructures/PhantomNodes.h"
#include "../DataStructures/SearchEngine.h"
#include "../Util/StringUtil.h"
#include "../Plugins/RawRouteData.h"
#include "../Util/StringUtil.h"
#include "../typedefs.h"
#include <cassert>
#include <cmath>
#include <cstdio>
#include <string>
#include <vector>
struct _DescriptorConfig {
_DescriptorConfig() : instructions(true), geometry(true), encodeGeometry(true), z(18) {}

View File

@ -91,7 +91,7 @@ void DescriptionFactory::Run(const SearchEngine &sEngine, const unsigned zoomLev
/** starts at index 1 */
pathDescription[0].length = 0;
for(unsigned i = 1; i < pathDescription.size(); ++i) {
pathDescription[i].length = ApproximateDistanceByEuclid(pathDescription[i-1].location, pathDescription[i].location);
pathDescription[i].length = ApproximateEuclideanDistance(pathDescription[i-1].location, pathDescription[i].location);
}
double lengthOfSegment = 0;

View File

@ -21,15 +21,15 @@
#ifndef DESCRIPTIONFACTORY_H_
#define DESCRIPTIONFACTORY_H_
#include <vector>
#include "../typedefs.h"
#include "../Algorithms/DouglasPeucker.h"
#include "../Algorithms/PolylineCompressor.h"
#include "../DataStructures/Coordinate.h"
#include "../DataStructures/SearchEngine.h"
#include "../DataStructures/SegmentInformation.h"
#include "../DataStructures/TurnInstructions.h"
#include "../typedefs.h"
#include <vector>
/* This class is fed with all way segments in consecutive order
* and produces the description plus the encoded polyline */

View File

@ -21,9 +21,10 @@ or see http://www.gnu.org/licenses/agpl.txt.
#ifndef GPX_DESCRIPTOR_H_
#define GPX_DESCRIPTOR_H_
#include <boost/foreach.hpp>
#include "BaseDescriptor.h"
#include <boost/foreach.hpp>
class GPXDescriptor : public BaseDescriptor{
private:
_DescriptorConfig config;

View File

@ -21,11 +21,6 @@ or see http://www.gnu.org/licenses/agpl.txt.
#ifndef JSON_DESCRIPTOR_H_
#define JSON_DESCRIPTOR_H_
#include <algorithm>
#include <boost/lambda/lambda.hpp>
#include <boost/bind.hpp>
#include "BaseDescriptor.h"
#include "DescriptionFactory.h"
#include "../Algorithms/ObjectToBase64.h"
@ -34,6 +29,11 @@ or see http://www.gnu.org/licenses/agpl.txt.
#include "../Util/Azimuth.h"
#include "../Util/StringUtil.h"
#include <boost/bind.hpp>
#include <boost/lambda/lambda.hpp>
#include <algorithm>
class JSONDescriptor : public BaseDescriptor{
private:
_DescriptorConfig config;
@ -41,7 +41,12 @@ private:
DescriptionFactory alternateDescriptionFactory;
_Coordinate current;
unsigned numberOfEnteredRestrictedAreas;
struct {
struct RoundAbout{
RoundAbout() :
startIndex(INT_MAX),
nameID(INT_MAX),
leaveAtExit(INT_MAX)
{}
int startIndex;
int nameID;
int leaveAtExit;

View File

@ -21,17 +21,17 @@ or see http://www.gnu.org/licenses/agpl.txt.
#ifndef BASEPARSER_H_
#define BASEPARSER_H_
#include "ExtractorCallbacks.h"
#include "ScriptingEnvironment.h"
extern "C" {
#include <lua.h>
#include <lauxlib.h>
#include <lualib.h>
#include <lua.h>
#include <lauxlib.h>
#include <lualib.h>
}
#include <boost/noncopyable.hpp>
#include "ExtractorCallbacks.h"
#include "ScriptingEnvironment.h"
class BaseParser : boost::noncopyable {
public:
BaseParser(ExtractorCallbacks* ec, ScriptingEnvironment& se);
@ -43,11 +43,11 @@ public:
virtual void ParseWayInLua(ExtractionWay& n, lua_State* luaStateForThread);
virtual void report_errors(lua_State *L, const int status) const;
protected:
protected:
virtual void ReadUseRestrictionsSetting();
virtual void ReadRestrictionExceptions();
virtual bool ShouldIgnoreRestriction(const std::string& except_tag_string) const;
ExtractorCallbacks* extractor_callbacks;
ScriptingEnvironment& scriptingEnvironment;
lua_State* luaState;

View File

@ -20,7 +20,7 @@
#include "ExtractionContainers.h"
void ExtractionContainers::PrepareData(const std::string & outputFileName, const std::string restrictionsFileName, const unsigned amountOfRAM) {
void ExtractionContainers::PrepareData(const std::string & output_file_name, const std::string restrictionsFileName, const unsigned amountOfRAM) {
try {
unsigned usedNodeCounter = 0;
unsigned usedEdgeCounter = 0;
@ -130,7 +130,7 @@ void ExtractionContainers::PrepareData(const std::string & outputFileName, const
restrictionsOutstream.close();
std::ofstream fout;
fout.open(outputFileName.c_str(), std::ios::binary);
fout.open(output_file_name.c_str(), std::ios::binary);
fout.write((char*)&usedNodeCounter, sizeof(unsigned));
time = get_timestamp();
std::cout << "[extractor] Confirming/Writing used nodes ... " << std::flush;
@ -271,7 +271,7 @@ void ExtractionContainers::PrepareData(const std::string & outputFileName, const
std::cout << "ok" << std::endl;
time = get_timestamp();
std::cout << "[extractor] writing street name index ... " << std::flush;
std::string nameOutFileName = (outputFileName + ".names");
std::string nameOutFileName = (output_file_name + ".names");
std::ofstream nameOutFile(nameOutFileName.c_str(), std::ios::binary);
unsigned sizeOfNameIndex = nameVector.size();
nameOutFile.write((char *)&(sizeOfNameIndex), sizeof(unsigned));

View File

@ -55,7 +55,7 @@ public:
wayStartEndVector.clear();
}
void PrepareData( const std::string & outputFileName, const std::string restrictionsFileName, const unsigned amountOfRAM);
void PrepareData( const std::string & output_file_name, const std::string restrictionsFileName, const unsigned amountOfRAM);
STXXLNodeIDVector usedNodeIDs;
STXXLNodeVector allNodes;

View File

@ -18,19 +18,16 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
or see http://www.gnu.org/licenses/agpl.txt.
*/
#ifndef EXTRACTIONHELPERFUNCTIONS_H_
#define EXTRACTIONHELPERFUNCTIONS_H_
#include "../Util/StringUtil.h"
#include <boost/algorithm/string.hpp>
#include <boost/algorithm/string_regex.hpp>
#include <boost/regex.hpp>
#include <climits>
#include "../Util/StringUtil.h"
namespace qi = boost::spirit::qi;
//TODO: Move into LUA

View File

@ -40,7 +40,6 @@ or see http://www.gnu.org/licenses/agpl.txt.
#include "ExtractorCallbacks.h"
#include "ExtractionHelperFunctions.h"
ExtractorCallbacks::ExtractorCallbacks() {externalMemory = NULL; stringMap = NULL; }
ExtractorCallbacks::ExtractorCallbacks(ExtractionContainers * ext, StringMap * strMap) {

View File

@ -31,6 +31,7 @@ or see http://www.gnu.org/licenses/agpl.txt.
#include <boost/regex.hpp>
#include "ExtractionContainers.h"
#include "ExtractionHelperFunctions.h"
#include "ExtractorStructs.h"
class ExtractorCallbacks{

View File

@ -21,13 +21,6 @@ or see http://www.gnu.org/licenses/agpl.txt.
#ifndef EXTRACTORSTRUCTS_H_
#define EXTRACTORSTRUCTS_H_
#include <climits>
#include <string>
#include <boost/algorithm/string.hpp>
#include <boost/algorithm/string/regex.hpp>
#include <boost/regex.hpp>
#include <boost/unordered_map.hpp>
#include "../DataStructures/Coordinate.h"
#include "../DataStructures/HashTable.h"
@ -37,6 +30,14 @@ or see http://www.gnu.org/licenses/agpl.txt.
#include "../DataStructures/TimingUtil.h"
#include "../typedefs.h"
#include <boost/algorithm/string.hpp>
#include <boost/algorithm/string/regex.hpp>
#include <boost/regex.hpp>
#include <boost/unordered_map.hpp>
#include <climits>
#include <string>
typedef boost::unordered_map<std::string, NodeID > StringMap;
typedef boost::unordered_map<std::string, std::pair<int, short> > StringToIntPairMap;
@ -44,7 +45,7 @@ struct ExtractionWay {
ExtractionWay() {
Clear();
}
inline void Clear(){
id = UINT_MAX;
nameID = UINT_MAX;

View File

@ -21,13 +21,14 @@
#ifndef PBFPARSER_H_
#define PBFPARSER_H_
#include "BaseParser.h"
#include "../DataStructures/HashTable.h"
#include "../DataStructures/ConcurrentQueue.h"
#include "../Util/MachineInfo.h"
#include "../Util/OpenMPWrapper.h"
#include "../typedefs.h"
#include "BaseParser.h"
#include <boost/shared_ptr.hpp>
#include <boost/make_shared.hpp>
#include <boost/ref.hpp>
@ -37,8 +38,6 @@
#include <zlib.h>
class PBFParser : public BaseParser {
enum EntityType {

View File

@ -21,20 +21,14 @@
#ifndef SCRIPTINGENVIRONMENT_H_
#define SCRIPTINGENVIRONMENT_H_
extern "C" {
#include <lua.h>
#include <lauxlib.h>
#include <lualib.h>
}
#include <luabind/luabind.hpp>
#include "ExtractionHelperFunctions.h"
#include "ExtractorStructs.h"
#include "../typedefs.h"
#include "../DataStructures/ImportNode.h"
#include "../Util/LuaUtil.h"
#include "../Util/OpenMPWrapper.h"
#include "../typedefs.h"
#include <vector>
class ScriptingEnvironment {
public:

View File

@ -18,14 +18,13 @@
or see http://www.gnu.org/licenses/agpl.txt.
*/
#include <boost/ref.hpp>
#include "XMLParser.h"
#include "ExtractorStructs.h"
#include "../DataStructures/HashTable.h"
#include "../DataStructures/InputReaderFactory.h"
#include <boost/ref.hpp>
XMLParser::XMLParser(const char * filename, ExtractorCallbacks* ec, ScriptingEnvironment& se) : BaseParser(ec, se) {
WARN("Parsing plain .osm/.osm.bz2 is deprecated. Switch to .pbf");
@ -43,12 +42,12 @@ bool XMLParser::Parse() {
if ( type != 1 ) {
continue;
}
xmlChar* currentName = xmlTextReaderName( inputReader );
if ( currentName == NULL ) {
continue;
}
if ( xmlStrEqual( currentName, ( const xmlChar* ) "node" ) == 1 ) {
ImportNode n = _ReadXMLNode();
ParseNodeInLua( n, luaState );

66
Library/OSRM.cpp Normal file
View File

@ -0,0 +1,66 @@
/*
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.
*/
#include "OSRM.h"
OSRM::OSRM(const char * server_ini_path) {
if( !testDataFile(server_ini_path) ){
throw OSRMException("server.ini not found");
}
BaseConfiguration serverConfig(server_ini_path);
objects = new QueryObjectsStorage(
serverConfig.GetParameter("hsgrData"),
serverConfig.GetParameter("ramIndex"),
serverConfig.GetParameter("fileIndex"),
serverConfig.GetParameter("nodesData"),
serverConfig.GetParameter("edgesData"),
serverConfig.GetParameter("namesData"),
serverConfig.GetParameter("timestamp")
);
RegisterPlugin(new HelloWorldPlugin());
RegisterPlugin(new LocatePlugin(objects));
RegisterPlugin(new NearestPlugin(objects));
RegisterPlugin(new TimestampPlugin(objects));
RegisterPlugin(new ViaRoutePlugin(objects));
}
OSRM::~OSRM() {
BOOST_FOREACH(PluginMap::value_type & plugin_pointer, pluginMap) {
delete plugin_pointer.second;
}
delete objects;
}
void OSRM::RegisterPlugin(BasePlugin * plugin) {
std::cout << "[plugin] " << plugin->GetDescriptor() << std::endl;
pluginMap[plugin->GetDescriptor()] = plugin;
}
void OSRM::RunQuery(RouteParameters & route_parameters, http::Reply & reply) {
const PluginMap::const_iterator & iter = pluginMap.find(route_parameters.service);
if(pluginMap.end() != iter) {
reply.status = http::Reply::ok;
iter->second->HandleRequest(route_parameters, reply );
} else {
reply = http::Reply::stockReply(http::Reply::badRequest);
}
}

66
Library/OSRM.h Normal file
View File

@ -0,0 +1,66 @@
/*
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 OSRM_H
#define OSRM_H
#include "OSRM.h"
#include "../Plugins/BasePlugin.h"
#include "../Plugins/HelloWorldPlugin.h"
#include "../Plugins/LocatePlugin.h"
#include "../Plugins/NearestPlugin.h"
#include "../Plugins/TimestampPlugin.h"
#include "../Plugins/ViaRoutePlugin.h"
#include "../Plugins/RouteParameters.h"
#include "../Util/BaseConfiguration.h"
#include "../Util/InputFileUtil.h"
#include "../Server/BasicDatastructures.h"
#include <boost/assert.hpp>
#include <boost/noncopyable.hpp>
#include <boost/thread.hpp>
#include <exception>
#include <vector>
class OSRMException: public std::exception {
public:
OSRMException(const char * message) : message(message) {}
private:
virtual const char* what() const throw() {
return message;
}
const char * message;
};
class OSRM : boost::noncopyable {
typedef boost::unordered_map<std::string, BasePlugin *> PluginMap;
QueryObjectsStorage * objects;
public:
OSRM(const char * server_ini_path);
~OSRM();
void RunQuery(RouteParameters & route_parameters, http::Reply & reply);
private:
void RegisterPlugin(BasePlugin * plugin);
PluginMap pluginMap;
};
#endif //OSRM_H

View File

@ -21,13 +21,12 @@ or see http://www.gnu.org/licenses/agpl.txt.
#ifndef BASEPLUGIN_H_
#define BASEPLUGIN_H_
#include <cassert>
#include <string>
#include <vector>
#include "RouteParameters.h"
#include "../Server/BasicDatastructures.h"
#include <string>
#include <vector>
class BasePlugin {
public:
BasePlugin() { }

View File

@ -8,15 +8,15 @@
#ifndef HELLOWORLDPLUGIN_H_
#define HELLOWORLDPLUGIN_H_
#include <sstream>
#include "BasePlugin.h"
#include "RouteParameters.h"
#include <sstream>
class HelloWorldPlugin : public BasePlugin {
public:
HelloWorldPlugin() {}
virtual ~HelloWorldPlugin() { /*std::cout << GetDescriptor() << " destructor" << std::endl;*/ }
virtual ~HelloWorldPlugin() { }
std::string GetDescriptor() const { return std::string("hello"); }
std::string GetVersionString() const { return std::string("0.1a"); }

View File

@ -21,16 +21,15 @@ or see http://www.gnu.org/licenses/agpl.txt.
#ifndef NearestPlugin_H_
#define NearestPlugin_H_
#include <fstream>
#include "BasePlugin.h"
#include "RouteParameters.h"
#include "../Server/DataStructures/QueryObjectsStorage.h"
#include "../DataStructures/NodeInformationHelpDesk.h"
#include "../Server/DataStructures/QueryObjectsStorage.h"
#include "../Util/StringUtil.h"
#include <fstream>
/*
* This Plugin locates the nearest point on a street in the road network for a given coordinate.
*/

View File

@ -1,34 +0,0 @@
/*
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 PLUGINMAPFACTORY_H_
#define PLUGINMAPFACTORY_H_
//#include "../DataStructures/HashTable.h"
//#include "../Plugins/BasePlugin.h"
//
//struct PluginMapFactory {
// static HashTable<std::string, BasePlugin *> * CreatePluginMap() {
// HashTable<std::string, BasePlugin *> * map = new HashTable<std::string, BasePlugin *>();
//
// }
//};
#endif /* PLUGINMAPFACTORY_H_ */

View File

@ -21,15 +21,25 @@ or see http://www.gnu.org/licenses/agpl.txt.
#ifndef ROUTE_PARAMETERS_H
#define ROUTE_PARAMETERS_H
#include "../DataStructures/Coordinate.h"
#include "../DataStructures/HashTable.h"
#include <boost/fusion/container/vector.hpp>
#include <boost/fusion/sequence/intrinsic.hpp>
#include <boost/fusion/include/at_c.hpp>
#include <string>
#include <vector>
#include <boost/fusion/sequence/intrinsic.hpp>
#include "../DataStructures/Coordinate.h"
struct RouteParameters {
RouteParameters() : zoomLevel(18), printInstructions(false), alternateRoute(true), geometry(true), compression(true), deprecatedAPI(false), checkSum(-1) {}
RouteParameters() :
zoomLevel(18),
printInstructions(false),
alternateRoute(true),
geometry(true),
compression(true),
deprecatedAPI(false),
checkSum(-1) {}
short zoomLevel;
bool printInstructions;
bool alternateRoute;

View File

@ -21,11 +21,11 @@ or see http://www.gnu.org/licenses/agpl.txt.
#ifndef TIMESTAMPPLUGIN_H_
#define TIMESTAMPPLUGIN_H_
#include <cassert>
#include "BasePlugin.h"
#include "RouteParameters.h"
#include <cassert>
class TimestampPlugin : public BasePlugin {
public:
TimestampPlugin(QueryObjectsStorage * o) : objects(o) {

View File

@ -21,29 +21,26 @@ or see http://www.gnu.org/licenses/agpl.txt.
#ifndef VIAROUTEPLUGIN_H_
#define VIAROUTEPLUGIN_H_
#include <cstdlib>
#include <fstream>
#include <sstream>
#include <string>
#include <vector>
#include "BasePlugin.h"
#include "RouteParameters.h"
#include "../Algorithms/ObjectToBase64.h"
#include "../Descriptors/BaseDescriptor.h"
#include "../Descriptors/GPXDescriptor.h"
#include "../Descriptors/JSONDescriptor.h"
#include "../DataStructures/HashTable.h"
#include "../DataStructures/QueryEdge.h"
#include "../DataStructures/StaticGraph.h"
#include "../DataStructures/SearchEngine.h"
#include "../Descriptors/BaseDescriptor.h"
#include "../Descriptors/GPXDescriptor.h"
#include "../Descriptors/JSONDescriptor.h"
#include "../Server/DataStructures/QueryObjectsStorage.h"
#include "../Util/StringUtil.h"
#include "../Server/DataStructures/QueryObjectsStorage.h"
#include <cstdlib>
#include <fstream>
#include <sstream>
#include <string>
#include <vector>
class ViaRoutePlugin : public BasePlugin {
private:
@ -94,7 +91,7 @@ public:
for(unsigned i = 0; i < rawRoute.rawViaNodeCoordinates.size(); ++i) {
if(checksumOK && i < routeParameters.hints.size() && "" != routeParameters.hints[i]) {
// INFO("Decoding hint: " << routeParameters.hints[i] << " for location index " << i);
DecodeObjectFromBase64(phantomNodeVector[i], routeParameters.hints[i]);
DecodeObjectFromBase64(routeParameters.hints[i], phantomNodeVector[i]);
if(phantomNodeVector[i].isValid(nodeHelpDesk->getNumberOfNodes())) {
// INFO("Decoded hint " << i << " successfully");
continue;

View File

@ -21,11 +21,10 @@ or see http://www.gnu.org/licenses/agpl.txt.
#ifndef ALTERNATIVEROUTES_H_
#define ALTERNATIVEROUTES_H_
#include <boost/unordered_map.hpp>
#include <vector>
#include <cmath>
#include "BasicRoutingInterface.h"
#include <boost/unordered_map.hpp>
#include <cmath>
#include <vector>
const double VIAPATH_ALPHA = 0.15;
const double VIAPATH_EPSILON = 0.10; //alternative at most 15% longer

View File

@ -73,23 +73,23 @@ public:
//insert new starting nodes into forward heap, adjusted by previous distances.
if(searchFrom1stStartNode) {
forward_heap1.Insert(phantomNodePair.startPhantom.edgeBasedNode, -phantomNodePair.startPhantom.weight1, phantomNodePair.startPhantom.edgeBasedNode);
INFO("fw1: " << phantomNodePair.startPhantom.edgeBasedNode << "´, w: " << -phantomNodePair.startPhantom.weight1);
// INFO("fw1: " << phantomNodePair.startPhantom.edgeBasedNode << "´, w: " << -phantomNodePair.startPhantom.weight1);
forward_heap2.Insert(phantomNodePair.startPhantom.edgeBasedNode, -phantomNodePair.startPhantom.weight1, phantomNodePair.startPhantom.edgeBasedNode);
INFO("fw2: " << phantomNodePair.startPhantom.edgeBasedNode << "´, w: " << -phantomNodePair.startPhantom.weight1);
// INFO("fw2: " << phantomNodePair.startPhantom.edgeBasedNode << "´, w: " << -phantomNodePair.startPhantom.weight1);
}
if(phantomNodePair.startPhantom.isBidirected() && searchFrom2ndStartNode) {
forward_heap1.Insert(phantomNodePair.startPhantom.edgeBasedNode+1, -phantomNodePair.startPhantom.weight2, phantomNodePair.startPhantom.edgeBasedNode+1);
INFO("fw1: " << phantomNodePair.startPhantom.edgeBasedNode+1 << "´, w: " << -phantomNodePair.startPhantom.weight2);
// INFO("fw1: " << phantomNodePair.startPhantom.edgeBasedNode+1 << "´, w: " << -phantomNodePair.startPhantom.weight2);
forward_heap2.Insert(phantomNodePair.startPhantom.edgeBasedNode+1, -phantomNodePair.startPhantom.weight2, phantomNodePair.startPhantom.edgeBasedNode+1);
INFO("fw2: " << phantomNodePair.startPhantom.edgeBasedNode+1 << "´, w: " << -phantomNodePair.startPhantom.weight2);
// INFO("fw2: " << phantomNodePair.startPhantom.edgeBasedNode+1 << "´, w: " << -phantomNodePair.startPhantom.weight2);
}
//insert new backward nodes into backward heap, unadjusted.
reverse_heap1.Insert(phantomNodePair.targetPhantom.edgeBasedNode, phantomNodePair.targetPhantom.weight1, phantomNodePair.targetPhantom.edgeBasedNode);
INFO("rv1: " << phantomNodePair.targetPhantom.edgeBasedNode << ", w;" << phantomNodePair.targetPhantom.weight1 );
// INFO("rv1: " << phantomNodePair.targetPhantom.edgeBasedNode << ", w;" << phantomNodePair.targetPhantom.weight1 );
if(phantomNodePair.targetPhantom.isBidirected() ) {
reverse_heap2.Insert(phantomNodePair.targetPhantom.edgeBasedNode+1, phantomNodePair.targetPhantom.weight2, phantomNodePair.targetPhantom.edgeBasedNode+1);
INFO("rv2: " << phantomNodePair.targetPhantom.edgeBasedNode+1 << ", w;" << phantomNodePair.targetPhantom.weight2 );
// INFO("rv2: " << phantomNodePair.targetPhantom.edgeBasedNode+1 << ", w;" << phantomNodePair.targetPhantom.weight2 );
}
const int forward_offset = phantomNodePair.startPhantom.weight1 + (phantomNodePair.startPhantom.isBidirected() ? phantomNodePair.startPhantom.weight2 : 0);
const int reverse_offset = phantomNodePair.targetPhantom.weight1 + (phantomNodePair.targetPhantom.isBidirected() ? phantomNodePair.targetPhantom.weight2 : 0);

View File

@ -20,12 +20,16 @@ or see http://www.gnu.org/licenses/agpl.txt.
#ifndef BASIC_DATASTRUCTURES_H
#define BASIC_DATASTRUCTURES_H
#include <string>
#include <sstream>
#include <boost/foreach.hpp>
#include "../Util/StringUtil.h"
#include <boost/asio.hpp>
#include <boost/foreach.hpp>
#include <string>
#include <sstream>
#include <vector>
namespace http {
const std::string okString = "HTTP/1.0 200 OK\r\n";
@ -77,7 +81,7 @@ struct Reply {
BOOST_FOREACH ( Header& h, headers) {
if("Content-Length" == h.name) {
std::string sizeString;
intToString(size,h.value );
intToString(size,h.value);
}
}
}
@ -139,7 +143,7 @@ Reply Reply::stockReply(Reply::status_type status) {
Reply rep;
rep.status = status;
rep.content = ToString(status);
rep.headers.resize(3);
rep.headers.resize(3);
rep.headers[0].name = "Access-Control-Allow-Origin";
rep.headers[0].value = "*";
rep.headers[1].name = "Content-Length";

View File

@ -21,7 +21,9 @@ or see http://www.gnu.org/licenses/agpl.txt.
#ifndef CONNECTION_H
#define CONNECTION_H
#include <vector>
#include "BasicDatastructures.h"
#include "RequestHandler.h"
#include "RequestParser.h"
#include <boost/asio.hpp>
#include <boost/array.hpp>
@ -30,11 +32,9 @@ or see http://www.gnu.org/licenses/agpl.txt.
#include <boost/shared_ptr.hpp>
#include <boost/enable_shared_from_this.hpp>
#include "BasicDatastructures.h"
#include "RequestHandler.h"
#include "RequestParser.h"
#include <zlib.h>
#include "zlib.h"
#include <vector>
namespace http {

View File

@ -23,13 +23,13 @@ or see http://www.gnu.org/licenses/agpl.txt.
#include "../../Util/GraphLoader.h"
QueryObjectsStorage::QueryObjectsStorage(
std::string hsgrPath,
std::string ramIndexPath,
std::string fileIndexPath,
std::string nodesPath,
std::string edgesPath,
std::string namesPath,
std::string timestampPath
const std::string & hsgrPath,
const std::string & ramIndexPath,
const std::string & fileIndexPath,
const std::string & nodesPath,
const std::string & edgesPath,
const std::string & namesPath,
const std::string & timestampPath
) {
INFO("loading graph data");
std::ifstream hsgrInStream(hsgrPath.c_str(), std::ios::binary);
@ -43,6 +43,7 @@ QueryObjectsStorage::QueryObjectsStorage(
edgeList,
&checkSum
);
hsgrInStream.close();
INFO("Data checksum is " << checkSum);
graph = new QueryGraph(nodeList, edgeList);
@ -68,7 +69,12 @@ QueryObjectsStorage::QueryObjectsStorage(
if(!nodesInStream) { ERR(nodesPath << " not found"); }
std::ifstream edgesInStream(edgesPath.c_str(), std::ios::binary);
if(!edgesInStream) { ERR(edgesPath << " not found"); }
nodeHelpDesk = new NodeInformationHelpDesk(ramIndexPath.c_str(), fileIndexPath.c_str(), n, checkSum);
nodeHelpDesk = new NodeInformationHelpDesk(
ramIndexPath.c_str(),
fileIndexPath.c_str(),
n,
checkSum
);
nodeHelpDesk->initNNGrid(nodesInStream, edgesInStream);
//deserialize street name list
@ -77,7 +83,6 @@ QueryObjectsStorage::QueryObjectsStorage(
if(!namesInStream) { ERR(namesPath << " not found"); }
unsigned size(0);
namesInStream.read((char *)&size, sizeof(unsigned));
// names = new std::vector<std::string>();
char buf[1024];
for(unsigned i = 0; i < size; ++i) {
@ -88,7 +93,6 @@ QueryObjectsStorage::QueryObjectsStorage(
names.push_back(buf);
}
std::vector<std::string>(names).swap(names);
hsgrInStream.close();
namesInStream.close();
INFO("All query data structures loaded");
}

View File

@ -30,8 +30,8 @@ or see http://www.gnu.org/licenses/agpl.txt.
#include "../../DataStructures/StaticGraph.h"
struct QueryObjectsStorage {
typedef StaticGraph<QueryEdge::EdgeData> QueryGraph;
typedef QueryGraph::InputEdge InputEdge;
typedef StaticGraph<QueryEdge::EdgeData> QueryGraph;
typedef QueryGraph::InputEdge InputEdge;
NodeInformationHelpDesk * nodeHelpDesk;
std::vector<std::string> names;
@ -39,7 +39,15 @@ struct QueryObjectsStorage {
std::string timestamp;
unsigned checkSum;
QueryObjectsStorage(std::string hsgrPath, std::string ramIndexPath, std::string fileIndexPath, std::string nodesPath, std::string edgesPath, std::string namesPath, std::string timestampPath);
QueryObjectsStorage(
const std::string & hsgrPath,
const std::string & ramIndexPath,
const std::string & fileIndexPath,
const std::string & nodesPath,
const std::string & edgesPath,
const std::string & namesPath,
const std::string & timestampPath
);
~QueryObjectsStorage();
};

View File

@ -21,35 +21,27 @@ or see http://www.gnu.org/licenses/agpl.txt.
#ifndef REQUEST_HANDLER_H
#define REQUEST_HANDLER_H
#include <algorithm>
#include <cctype> // std::tolower
#include <string>
#include <iostream>
#include <boost/noncopyable.hpp>
#include "APIGrammar.h"
#include "BasicDatastructures.h"
#include "../DataStructures/HashTable.h"
#include "../Plugins/BasePlugin.h"
#include "../Library/OSRM.h"
#include "../Plugins/RouteParameters.h"
#include "../Util/StringUtil.h"
#include "../typedefs.h"
namespace http {
#include <boost/foreach.hpp>
#include <boost/noncopyable.hpp>
#include <algorithm>
#include <iostream>
#include <iterator>
#include <string>
class RequestHandler : private boost::noncopyable {
public:
explicit RequestHandler() : _pluginCount(0) { }
typedef APIGrammar<std::string::iterator, RouteParameters> APIGrammarParser;
explicit RequestHandler() { }
~RequestHandler() {
for(unsigned i = 0; i < _pluginVector.size(); i++) {
BasePlugin * tempPointer = _pluginVector[i];
delete tempPointer;
}
}
void handle_request(const Request& req, Reply& rep){
void handle_request(const http::Request& req, http::Reply& rep){
//parse command
try {
std::string request(req.uri);
@ -66,10 +58,10 @@ public:
}
RouteParameters routeParameters;
APIGrammar<std::string::iterator, RouteParameters> apiParser(&routeParameters);
APIGrammarParser apiParser(&routeParameters);
std::string::iterator it = request.begin();
bool result = boost::spirit::qi::parse(it, request.end(), apiParser); // returns true if successful
bool result = boost::spirit::qi::parse(it, request.end(), apiParser);
if (!result || (it != request.end()) ) {
rep = http::Reply::stockReply(http::Reply::badRequest);
int position = std::distance(request.begin(), it);
@ -80,38 +72,29 @@ public:
rep.content += request;
rep.content += tmp_position_string;
rep.content += "<br>";
for(unsigned i = 0, end = std::distance(request.begin(), it); i < end; ++i)
unsigned end = std::distance(request.begin(), it);
for(unsigned i = 0; i < end; ++i) {
rep.content += "&nbsp;";
}
rep.content += "^<br></pre>";
} else {
//Finished parsing, lets call the right plugin to handle the request
if(pluginMap.Holds(routeParameters.service)) {
rep.status = Reply::ok;
_pluginVector[pluginMap.Find(routeParameters.service)]->HandleRequest(routeParameters, rep );
} else {
rep = Reply::stockReply(Reply::badRequest);
}
//parsing done, lets call the right plugin to handle the request
routing_machine->RunQuery(routeParameters, rep);
return;
}
} catch(std::exception& e) {
rep = Reply::stockReply(Reply::internalServerError);
std::cerr << "[server error] code: " << e.what() << ", uri: " << req.uri << std::endl;
rep = http::Reply::stockReply(http::Reply::internalServerError);
WARN("[server error] code: " << e.what() << ", uri: " << req.uri);
return;
}
};
void RegisterPlugin(BasePlugin * plugin) {
std::cout << "[handler] registering plugin " << plugin->GetDescriptor() << std::endl;
pluginMap.Add(plugin->GetDescriptor(), _pluginCount);
_pluginVector.push_back(plugin);
++_pluginCount;
void RegisterRoutingMachine(OSRM * osrm) {
routing_machine = osrm;
}
private:
HashTable<std::string, unsigned> pluginMap;
std::vector<BasePlugin *> _pluginVector;
unsigned _pluginCount;
OSRM * routing_machine;
};
} // namespace http
#endif // REQUEST_HANDLER_H

View File

@ -21,21 +21,29 @@ or see http://www.gnu.org/licenses/agpl.txt.
#ifndef SERVER_H
#define SERVER_H
#include <vector>
#include "Connection.h"
#include "RequestHandler.h"
#include <boost/asio.hpp>
#include <boost/bind.hpp>
#include <boost/noncopyable.hpp>
#include <boost/shared_ptr.hpp>
#include <boost/thread.hpp>
#include "Connection.h"
#include "RequestHandler.h"
namespace http {
#include <vector>
class Server: private boost::noncopyable {
public:
explicit Server(const std::string& address, const std::string& port, unsigned thread_pool_size) : threadPoolSize(thread_pool_size), acceptor(ioService), newConnection(new Connection(ioService, requestHandler)), requestHandler(){
explicit Server(
const std::string& address,
const std::string& port,
unsigned thread_pool_size
) :
threadPoolSize(thread_pool_size),
acceptor(ioService),
newConnection(new http::Connection(ioService, requestHandler)),
requestHandler()
{
boost::asio::ip::tcp::resolver resolver(ioService);
boost::asio::ip::tcp::resolver::query query(address, port);
boost::asio::ip::tcp::endpoint endpoint = *resolver.resolve(query);
@ -44,7 +52,14 @@ public:
acceptor.set_option(boost::asio::ip::tcp::acceptor::reuse_address(true));
acceptor.bind(endpoint);
acceptor.listen();
acceptor.async_accept(newConnection->socket(), boost::bind(&Server::handleAccept, this, boost::asio::placeholders::error));
acceptor.async_accept(
newConnection->socket(),
boost::bind(
&Server::handleAccept,
this,
boost::asio::placeholders::error
)
);
}
void Run() {
@ -66,23 +81,28 @@ public:
}
private:
typedef boost::shared_ptr<Connection > ConnectionPtr;
void handleAccept(const boost::system::error_code& e) {
if (!e) {
newConnection->start();
newConnection.reset(new Connection(ioService, requestHandler));
acceptor.async_accept(newConnection->socket(), boost::bind(&Server::handleAccept, this, boost::asio::placeholders::error));
newConnection.reset(
new http::Connection(ioService, requestHandler)
);
acceptor.async_accept(
newConnection->socket(),
boost::bind(
&Server::handleAccept,
this,
boost::asio::placeholders::error
)
);
}
}
unsigned threadPoolSize;
boost::asio::io_service ioService;
boost::asio::ip::tcp::acceptor acceptor;
ConnectionPtr newConnection;
boost::shared_ptr<http::Connection> newConnection;
RequestHandler requestHandler;
};
} // namespace http
#endif // SERVER_H

View File

@ -1,28 +0,0 @@
/*
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 SERVERCONFIGURATION_H_
#define SERVERCONFIGURATION_H_
#include "../Util/BaseConfiguration.h"
typedef BaseConfiguration ServerConfiguration;
#endif /* SERVERCONFIGURATION_H_ */

View File

@ -25,21 +25,19 @@ or see http://www.gnu.org/licenses/agpl.txt.
#ifndef SERVERFACTORY_H_
#define SERVERFACTORY_H_
#include <zlib.h>
#include "Server.h"
#include "ServerConfiguration.h"
#include "../Util/BaseConfiguration.h"
#include "../Util/InputFileUtil.h"
#include "../Util/OpenMPWrapper.h"
#include "../Util/StringUtil.h"
#include "../typedefs.h"
typedef http::Server Server;
#include <zlib.h>
struct ServerFactory {
static Server * CreateServer(ServerConfiguration& serverConfig) {
static Server * CreateServer(BaseConfiguration& serverConfig) {
if(!testDataFile(serverConfig.GetParameter("nodesData"))) {
ERR("nodes file not found");
@ -76,7 +74,7 @@ struct ServerFactory {
}
static Server * CreateServer(const char * iniFile) {
ServerConfiguration serverConfig(iniFile);
BaseConfiguration serverConfig(iniFile);
return CreateServer(serverConfig);
}
};

View File

@ -18,23 +18,6 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
or see http://www.gnu.org/licenses/agpl.txt.
*/
#define VERBOSE(x) x
#define VERBOSE2(x)
#ifdef NDEBUG
#undef VERBOSE
#undef VERBOSE2
#endif
#include <boost/foreach.hpp>
#include <fstream>
#include <istream>
#include <iostream>
#include <cstring>
#include <string>
#include <vector>
#include "../typedefs.h"
#include "../Algorithms/StronglyConnectedComponents.h"
#include "../DataStructures/BinaryHeap.h"
@ -46,57 +29,93 @@ or see http://www.gnu.org/licenses/agpl.txt.
#include "../Util/InputFileUtil.h"
#include "../Util/GraphLoader.h"
using namespace std;
#include <boost/foreach.hpp>
#include <fstream>
#include <istream>
#include <iostream>
#include <cstring>
#include <string>
#include <vector>
typedef QueryEdge::EdgeData EdgeData;
typedef QueryEdge::EdgeData EdgeData;
typedef DynamicGraph<EdgeData>::InputEdge InputEdge;
typedef BaseConfiguration ContractorConfiguration;
typedef BaseConfiguration ContractorConfiguration;
std::vector<NodeInfo> internalToExternalNodeMapping;
std::vector<_Restriction> inputRestrictions;
std::vector<NodeID> bollardNodes;
std::vector<NodeID> trafficLightNodes;
std::vector<NodeInfo> internal_to_external_node_map;
std::vector<_Restriction> restrictions_vector;
std::vector<NodeID> bollard_node_IDs_vector;
std::vector<NodeID> traffic_light_node_IDs_vector;
int main (int argc, char *argv[]) {
if(argc < 3) {
ERR("usage: " << std::endl << argv[0] << " <osrm-data> <osrm-restrictions>");
int main (int argument_count, char *argument_values[]) {
if(argument_count < 3) {
ERR("usage:\n" << argument_values[0] << " <osrm> <osrm.restrictions>");
}
std::string SRTM_ROOT;
INFO("Using restrictions from file: " << argv[2]);
std::ifstream restrictionsInstream(argv[2], ios::binary);
if(!restrictionsInstream.good()) {
INFO("Using restrictions from file: " << argument_values[2]);
std::ifstream restriction_ifstream(argument_values[2], std::ios::binary);
if(!restriction_ifstream.good()) {
ERR("Could not access <osrm-restrictions> files");
}
_Restriction restriction;
unsigned usableRestrictionsCounter(0);
restrictionsInstream.read((char*)&usableRestrictionsCounter, sizeof(unsigned));
inputRestrictions.resize(usableRestrictionsCounter);
restrictionsInstream.read((char *)&(inputRestrictions[0]), usableRestrictionsCounter*sizeof(_Restriction));
restrictionsInstream.close();
uint32_t usable_restriction_count = 0;
restriction_ifstream.read(
(char*)&usable_restriction_count,
sizeof(uint32_t)
);
restrictions_vector.resize(usable_restriction_count);
std::ifstream in;
in.open (argv[1], std::ifstream::in | std::ifstream::binary);
if (!in.is_open()) {
ERR("Cannot open " << argv[1]);
restriction_ifstream.read(
(char *)&(restrictions_vector[0]),
usable_restriction_count*sizeof(_Restriction)
);
restriction_ifstream.close();
std::ifstream input_stream;
input_stream.open(
argument_values[1],
std::ifstream::in | std::ifstream::binary
);
if (!input_stream.is_open()) {
ERR("Cannot open " << argument_values[1]);
}
std::vector<ImportEdge> edgeList;
NodeID nodeBasedNodeNumber = readBinaryOSRMGraphFromStream(in, edgeList, bollardNodes, trafficLightNodes, &internalToExternalNodeMapping, inputRestrictions);
in.close();
INFO(inputRestrictions.size() << " restrictions, " << bollardNodes.size() << " bollard nodes, " << trafficLightNodes.size() << " traffic lights");
std::vector<ImportEdge> edge_list;
NodeID node_based_node_count = readBinaryOSRMGraphFromStream(
input_stream,
edge_list,
bollard_node_IDs_vector,
traffic_light_node_IDs_vector,
&internal_to_external_node_map,
restrictions_vector
);
input_stream.close();
INFO(
restrictions_vector.size() << " restrictions, " <<
bollard_node_IDs_vector.size() << " bollard nodes, " <<
traffic_light_node_IDs_vector.size() << " traffic lights"
);
/***
* Building an edge-expanded graph from node-based input an turn restrictions
*/
INFO("Starting SCC graph traversal");
TarjanSCC * tarjan = new TarjanSCC (nodeBasedNodeNumber, edgeList, bollardNodes, trafficLightNodes, inputRestrictions, internalToExternalNodeMapping);
std::vector<ImportEdge>().swap(edgeList);
TarjanSCC * tarjan = new TarjanSCC (
node_based_node_count,
edge_list,
bollard_node_IDs_vector,
traffic_light_node_IDs_vector,
restrictions_vector,
internal_to_external_node_map
);
std::vector<ImportEdge>().swap(edge_list);
tarjan->Run();
std::vector<_Restriction>().swap(inputRestrictions);
std::vector<NodeID>().swap(bollardNodes);
std::vector<NodeID>().swap(trafficLightNodes);
std::vector<_Restriction>().swap(restrictions_vector);
std::vector<NodeID>().swap(bollard_node_IDs_vector);
std::vector<NodeID>().swap(traffic_light_node_IDs_vector);
INFO("finished component analysis");
return 0;
}

86
Tools/simpleclient.cpp Normal file
View File

@ -0,0 +1,86 @@
/*
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.
*/
#include "../Library/OSRM.h"
#include <boost/property_tree/ptree.hpp>
#include <boost/property_tree/json_parser.hpp>
#include <iostream>
#include <stack>
#include <string>
#include <sstream>
//Dude, real recursions on the OS stack? You must be brave...
void print_tree(boost::property_tree::ptree const& pt, const unsigned recursion_depth)
{
boost::property_tree::ptree::const_iterator end = pt.end();
for (boost::property_tree::ptree::const_iterator it = pt.begin(); it != end; ++it) {
for(unsigned i = 0; i < recursion_depth; ++i) {
std::cout << " " << std::flush;
}
std::cout << it->first << ": " << it->second.get_value<std::string>() << std::endl;
print_tree(it->second, recursion_depth+1);
}
}
int main (int argc, char * argv[]) {
std::cout << "\n starting up engines, compile at "
<< __DATE__ << ", " __TIME__ << std::endl;
BaseConfiguration serverConfig((argc > 1 ? argv[1] : "server.ini"));
OSRM routing_machine((argc > 1 ? argv[1] : "server.ini"));
RouteParameters route_parameters;
route_parameters.zoomLevel = 18; //no generalization
route_parameters.printInstructions = true; //turn by turn instructions
route_parameters.alternateRoute = true; //get an alternate route, too
route_parameters.geometry = true; //retrieve geometry of route
route_parameters.compression = true; //polyline encoding
route_parameters.checkSum = UINT_MAX; //see wiki
route_parameters.service = "viaroute"; //that's routing
route_parameters.outputFormat = "json";
route_parameters.jsonpParameter = ""; //set for jsonp wrapping
route_parameters.language = ""; //unused atm
//route_parameters.hints.push_back(); // see wiki, saves I/O if done properly
_Coordinate start_coordinate(52.519930*100000,13.438640*100000);
_Coordinate target_coordinate(52.513191*100000,13.415852*100000);
route_parameters.coordinates.push_back(start_coordinate);
route_parameters.coordinates.push_back(target_coordinate);
http::Reply osrm_reply;
routing_machine.RunQuery(route_parameters, osrm_reply);
std::cout << osrm_reply.content << std::endl;
//attention: super-inefficient hack below:
std::stringstream ss;
ss << osrm_reply.content;
boost::property_tree::ptree pt;
boost::property_tree::read_json(ss, pt);
print_tree(pt, 0);
return 0;
}

View File

@ -21,12 +21,12 @@ or see http://www.gnu.org/licenses/agpl.txt.
#ifndef BASECONFIGURATION_H_
#define BASECONFIGURATION_H_
#include <iostream>
#include <string>
#include "../DataStructures/HashTable.h"
#include <exception>
#include <fstream>
#include "../DataStructures/HashTable.h"
#include <iostream>
#include <string>
class BaseConfiguration {
public:
@ -73,7 +73,11 @@ public:
}
private:
void Tokenize(const std::string& str, std::vector<std::string>& tokens, const std::string& delimiters = "=") {
void Tokenize(
const std::string& str,
std::vector<std::string>& tokens,
const std::string& delimiters = "="
) {
std::string::size_type lastPos = str.find_first_not_of(delimiters, 0);
std::string::size_type pos = str.find_first_of(delimiters, lastPos);
@ -86,6 +90,7 @@ private:
pos = str.find_first_of(delimiters, lastPos);
}
}
void TrimStringRight(std::string& str) {
std::string::size_type pos = str.find_last_not_of(" ");
if (pos != std::string::npos)
@ -93,6 +98,7 @@ private:
else
str.erase( str.begin() , str.end() );
}
void TrimStringLeft(std::string& str) {
std::string::size_type pos = str.find_first_not_of(" ");
if (pos != std::string::npos)

View File

@ -21,10 +21,10 @@ or see http://www.gnu.org/licenses/agpl.txt.
#ifndef INPUTFILEUTIL_H_
#define INPUTFILEUTIL_H_
#include <boost/filesystem.hpp>
#include "../typedefs.h"
#include <boost/filesystem.hpp>
// Check if file exists and if it can be opened for reading with ifstream an object
inline bool testDataFile(const std::string & filename){
boost::filesystem::path fileToTest(filename);

View File

@ -25,7 +25,6 @@ or see http://www.gnu.org/licenses/agpl.txt.
#include <string>
#ifdef __linux__
#include <cxxabi.h>
#include <execinfo.h>

View File

@ -1,17 +1,17 @@
/*
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
@ -23,11 +23,11 @@
#if defined(__APPLE__) || defined(__FreeBSD__)
extern "C" {
#include <sys/types.h>
#include <sys/sysctl.h>
}
#include <sys/types.h>
#include <sys/sysctl.h>
}
#elif defined _WIN32
#include <windows.h>
#include <windows.h>
#endif
enum Endianness {
@ -55,28 +55,28 @@ inline unsigned swapEndian(unsigned x) {
inline unsigned GetPhysicalmemory(void){
#if defined(SUN5) || defined(__linux__)
return (sysconf(_SC_PHYS_PAGES) * sysconf(_SC_PAGESIZE));
#elif defined(__APPLE__)
int mib[2] = {CTL_HW, HW_MEMSIZE};
long long memsize;
size_t len = sizeof(memsize);
sysctl(mib, 2, &memsize, &len, NULL, 0);
return memsize/1024;
#elif defined(__FreeBSD__)
int mib[2] = {CTL_HW, HW_PHYSMEM};
long long memsize;
size_t len = sizeof(memsize);
sysctl(mib, 2, &memsize, &len, NULL, 0);
return memsize/1024;
#elif defined(_WIN32)
MEMORYSTATUSEX status;
status.dwLength = sizeof(status);
GlobalMemoryStatusEx(&status);
return status.ullTotalPhys/1024;
#else
std::cout << "[Warning] Compiling on unknown architecture." << std::endl
std::cout << "[Warning] Compiling on unknown architecture." << std::endl
<< "Please file a ticket at http://project-osrm.org" << std::endl;
return 2048*1024; /* 128 Mb default memory */

View File

@ -19,16 +19,17 @@ or see http://www.gnu.org/licenses/agpl.txt.
*/
#ifndef _OPENMPREPLACEMENTY_H
#define _OPENMPREPLACEMENTY_H
#ifndef _OPENMWRAPPER_H
#define _OPENMWRAPPER_H
#ifdef _OPENMP
#include <omp.h>
extern "C" {
#include <omp.h>
}
#else
inline const int omp_get_num_procs() { return 1; }
inline const int omp_get_max_threads() { return 1; }
inline const int omp_get_thread_num() { return 0; }
inline const void omp_set_num_threads(int i) {}
#endif
#endif
inline int omp_get_num_procs () { return 1; }
inline int omp_get_max_threads () { return 1; }
inline int omp_get_thread_num () { return 0; }
inline void omp_set_num_threads (int i) {}
#endif /* _OPENMP */
#endif /* _OPENMWRAPPER_H */

View File

@ -21,6 +21,8 @@ or see http://www.gnu.org/licenses/agpl.txt.
#ifndef STRINGUTIL_H_
#define STRINGUTIL_H_
#include "../typedefs.h"
#include <string>
#include <boost/algorithm/string.hpp>
@ -29,9 +31,6 @@ or see http://www.gnu.org/licenses/agpl.txt.
#include <cstdio>
#include "../DataStructures/Coordinate.h"
#include "../typedefs.h"
// precision: position after decimal point
// length: maximum number of digits including comma and decimals
template< int length, int precision >
@ -94,32 +93,6 @@ static inline void doubleToStringWithTwoDigitsBehindComma(const double value, st
output = buffer ;
}
static inline void convertInternalLatLonToString(const int value, std::string & output) {
char buffer[100];
buffer[10] = 0; // Nullterminierung
char* string = printInt< 10, 5 >( buffer, value );
output = string;
}
static inline void convertInternalCoordinateToString(const _Coordinate & coord, std::string & output) {
std::string tmp;
convertInternalLatLonToString(coord.lon, tmp);
output = tmp;
output += ",";
convertInternalLatLonToString(coord.lat, tmp);
output += tmp;
output += " ";
}
static inline void convertInternalReversedCoordinateToString(const _Coordinate & coord, std::string & output) {
std::string tmp;
convertInternalLatLonToString(coord.lat, tmp);
output = tmp;
output += ",";
convertInternalLatLonToString(coord.lon, tmp);
output += tmp;
output += " ";
}
inline void replaceAll(std::string &s, const std::string &sub, const std::string &other) {
boost::replace_all(s, sub, other);
}

View File

@ -63,14 +63,14 @@ int main (int argc, char *argv[]) {
}
double startupTime = get_timestamp();
unsigned numberOfThreads = omp_get_num_procs();
unsigned number_of_threads = omp_get_num_procs();
if(testDataFile("contractor.ini")) {
ContractorConfiguration contractorConfig("contractor.ini");
unsigned rawNumber = stringToInt(contractorConfig.GetParameter("Threads"));
if(rawNumber != 0 && rawNumber <= numberOfThreads)
numberOfThreads = rawNumber;
if(rawNumber != 0 && rawNumber <= number_of_threads)
number_of_threads = rawNumber;
}
omp_set_num_threads(numberOfThreads);
omp_set_num_threads(number_of_threads);
INFO("Using restrictions from file: " << argv[2]);
std::ifstream restrictionsInstream(argv[2], std::ios::binary);

View File

@ -31,93 +31,100 @@ or see http://www.gnu.org/licenses/agpl.txt.
#include "typedefs.h"
#include <cstdlib>
#include <iostream>
#include <fstream>
#include <string>
typedef BaseConfiguration ExtractorConfiguration;
ExtractorCallbacks * extractCallBacks;
int main (int argc, char *argv[]) {
double earliestTime = get_timestamp();
try {
double startup_time = get_timestamp();
if(argc < 2) {
ERR("usage: \n" << argv[0] << " <file.osm/.osm.bz2/.osm.pbf> [<profile.lua>]");
}
/*** Setup Scripting Environment ***/
ScriptingEnvironment scriptingEnvironment((argc > 2 ? argv[2] : "profile.lua"));
unsigned numberOfThreads = omp_get_num_procs();
if(testDataFile("extractor.ini")) {
ExtractorConfiguration extractorConfig("extractor.ini");
unsigned rawNumber = stringToInt(extractorConfig.GetParameter("Threads"));
if( rawNumber != 0 && rawNumber <= numberOfThreads)
numberOfThreads = rawNumber;
}
omp_set_num_threads(numberOfThreads);
INFO("extracting data from input file " << argv[1]);
bool isPBF(false);
std::string outputFileName(argv[1]);
std::string restrictionsFileName(argv[1]);
std::string::size_type pos = outputFileName.find(".osm.bz2");
if(pos==std::string::npos) {
pos = outputFileName.find(".osm.pbf");
if(pos!=std::string::npos) {
isPBF = true;
if(argc < 2) {
ERR("usage: \n" << argv[0] << " <file.osm/.osm.bz2/.osm.pbf> [<profile.lua>]");
}
/*** Setup Scripting Environment ***/
ScriptingEnvironment scriptingEnvironment((argc > 2 ? argv[2] : "profile.lua"));
unsigned number_of_threads = omp_get_num_procs();
if(testDataFile("extractor.ini")) {
BaseConfiguration extractorConfig("extractor.ini");
unsigned rawNumber = stringToInt(extractorConfig.GetParameter("Threads"));
if( rawNumber != 0 && rawNumber <= number_of_threads) {
number_of_threads = rawNumber;
}
}
omp_set_num_threads(number_of_threads);
INFO("extracting data from input file " << argv[1]);
bool file_has_pbf_format(false);
std::string output_file_name(argv[1]);
std::string restrictionsFileName(argv[1]);
std::string::size_type pos = output_file_name.find(".osm.bz2");
if(pos==std::string::npos) {
pos = output_file_name.find(".osm.pbf");
if(pos!=std::string::npos) {
file_has_pbf_format = true;
}
}
}
if(pos!=std::string::npos) {
outputFileName.replace(pos, 8, ".osrm");
restrictionsFileName.replace(pos, 8, ".osrm.restrictions");
} else {
pos=outputFileName.find(".osm");
if(pos!=std::string::npos) {
outputFileName.replace(pos, 5, ".osrm");
restrictionsFileName.replace(pos, 5, ".osrm.restrictions");
output_file_name.replace(pos, 8, ".osrm");
restrictionsFileName.replace(pos, 8, ".osrm.restrictions");
} else {
outputFileName.append(".osrm");
restrictionsFileName.append(".osrm.restrictions");
pos=output_file_name.find(".osm");
if(pos!=std::string::npos) {
output_file_name.replace(pos, 5, ".osrm");
restrictionsFileName.replace(pos, 5, ".osrm.restrictions");
} else {
output_file_name.append(".osrm");
restrictionsFileName.append(".osrm.restrictions");
}
}
unsigned amountOfRAM = 1;
unsigned installedRAM = GetPhysicalmemory();
if(installedRAM < 2048264) {
WARN("Machine has less than 2GB RAM.");
}
StringMap stringMap;
ExtractionContainers externalMemory;
stringMap[""] = 0;
extractCallBacks = new ExtractorCallbacks(&externalMemory, &stringMap);
BaseParser* parser;
if(file_has_pbf_format) {
parser = new PBFParser(argv[1], extractCallBacks, scriptingEnvironment);
} else {
parser = new XMLParser(argv[1], extractCallBacks, scriptingEnvironment);
}
if(!parser->ReadHeader()) {
ERR("Parser not initialized!");
}
INFO("Parsing in progress..");
double parsing_start_time = get_timestamp();
parser->Parse();
INFO("Parsing finished after " <<
(get_timestamp() - parsing_start_time) <<
" seconds"
);
externalMemory.PrepareData(output_file_name, restrictionsFileName, amountOfRAM);
delete parser;
delete extractCallBacks;
INFO("extraction finished after " << get_timestamp() - startup_time << "s");
std::cout << "\nRun:\n"
<< "./osrm-prepare " << output_file_name << " " << restrictionsFileName
<< std::endl;
return 0;
} catch(std::exception & e) {
WARN("unhandled exception: " << e.what());
}
unsigned amountOfRAM = 1;
unsigned installedRAM = GetPhysicalmemory();
if(installedRAM < 2048264) {
WARN("Machine has less than 2GB RAM.");
}
StringMap stringMap;
ExtractionContainers externalMemory;
stringMap[""] = 0;
extractCallBacks = new ExtractorCallbacks(&externalMemory, &stringMap);
BaseParser* parser;
if(isPBF) {
parser = new PBFParser(argv[1], extractCallBacks, scriptingEnvironment);
} else {
parser = new XMLParser(argv[1], extractCallBacks, scriptingEnvironment);
}
if(!parser->ReadHeader()) {
ERR("Parser not initialized!");
}
INFO("Parsing in progress..");
double time = get_timestamp();
parser->Parse();
INFO("Parsing finished after " << get_timestamp() - time << " seconds");
externalMemory.PrepareData(outputFileName, restrictionsFileName, amountOfRAM);
stringMap.clear();
delete parser;
delete extractCallBacks;
INFO("finished after " << get_timestamp() - earliestTime << "s");
std::cout << "\nRun:\n"
"./osrm-prepare " << outputFileName << " " << restrictionsFileName << std::endl;
return 0;
}

View File

@ -17,34 +17,28 @@ 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.
*/
#include "Library/OSRM.h"
#include "Server/ServerFactory.h"
#include "Util/BaseConfiguration.h"
#include "Util/InputFileUtil.h"
#include "Util/OpenMPWrapper.h"
#ifdef __linux__
#include "Util/LinuxStackTrace.h"
#include <sys/mman.h>
#endif
#include <iostream>
#include <signal.h>
#include <boost/bind.hpp>
#include <boost/date_time.hpp>
#include <boost/thread.hpp>
#include "Server/DataStructures/QueryObjectsStorage.h"
#include "Server/ServerConfiguration.h"
#include "Server/ServerFactory.h"
#include "Plugins/HelloWorldPlugin.h"
#include "Plugins/LocatePlugin.h"
#include "Plugins/NearestPlugin.h"
#include "Plugins/TimestampPlugin.h"
#include "Plugins/ViaRoutePlugin.h"
#include "Util/InputFileUtil.h"
#include "Util/OpenMPWrapper.h"
#ifndef _WIN32
#include "Util/LinuxStackTrace.h"
#endif
typedef http::RequestHandler RequestHandler;
#include <iostream>
#ifdef _WIN32
boost::function0<void> console_ctrl_function;
@ -70,7 +64,7 @@ int main (int argc, char * argv[]) {
if(!mlockall(MCL_CURRENT | MCL_FUTURE))
WARN("Process " << argv[0] << "could not be locked to RAM");
#endif
#ifndef _WIN32
#ifdef __linux__
installCrashHandler(argv[0]);
#endif
@ -83,7 +77,8 @@ int main (int argc, char * argv[]) {
//}
try {
std::cout << std::endl << "[server] starting up engines, saved at " << __TIMESTAMP__ << std::endl;
std::cout << "\n starting up engines, compile at " <<
__DATE__ << ", " __TIME__ << std::endl;
#ifndef _WIN32
int sig = 0;
@ -93,28 +88,11 @@ int main (int argc, char * argv[]) {
pthread_sigmask(SIG_BLOCK, &new_mask, &old_mask);
#endif
ServerConfiguration serverConfig((argc > 1 ? argv[1] : "server.ini"));
BaseConfiguration serverConfig((argc > 1 ? argv[1] : "server.ini"));
OSRM routing_machine((argc > 1 ? argv[1] : "server.ini"));
Server * s = ServerFactory::CreateServer(serverConfig);
RequestHandler & h = s->GetRequestHandlerPtr();
QueryObjectsStorage * objects = new QueryObjectsStorage(serverConfig.GetParameter("hsgrData"),
serverConfig.GetParameter("ramIndex"),
serverConfig.GetParameter("fileIndex"),
serverConfig.GetParameter("nodesData"),
serverConfig.GetParameter("edgesData"),
serverConfig.GetParameter("namesData"),
serverConfig.GetParameter("timestamp")
);
h.RegisterPlugin(new HelloWorldPlugin());
h.RegisterPlugin(new LocatePlugin(objects));
h.RegisterPlugin(new NearestPlugin(objects));
h.RegisterPlugin(new TimestampPlugin(objects));
h.RegisterPlugin(new ViaRoutePlugin(objects));
s->GetRequestHandlerPtr().RegisterRoutingMachine(&routing_machine);
boost::thread t(boost::bind(&Server::Run, s));
@ -146,7 +124,6 @@ int main (int argc, char * argv[]) {
std::cout << "[server] freeing objects" << std::endl;
delete s;
delete objects;
std::cout << "[server] shutdown completed" << std::endl;
} catch (std::exception& e) {
std::cerr << "[fatal error] exception: " << e.what() << std::endl;

View File

@ -2,10 +2,10 @@ Threads = 8
IP = 0.0.0.0
Port = 5000
hsgrData=/opt/osm/berlin.osrm.hsgr
nodesData=/opt/osm/berlin.osrm.nodes
edgesData=/opt/osm/berlin.osrm.edges
ramIndex=/opt/osm/berlin.osrm.ramIndex
fileIndex=/opt/osm/berlin.osrm.fileIndex
namesData=/opt/osm/berlin.osrm.names
timestamp=/opt/osm/berlin.osrm.timestamp
hsgrData=/Users/dennisluxen/Downloads/berlin-latest.osrm.hsgr
nodesData=/Users/dennisluxen/Downloads/berlin-latest.osrm.nodes
edgesData=/Users/dennisluxen/Downloads/berlin-latest.osrm.edges
ramIndex=/Users/dennisluxen/Downloads/berlin-latest.osrm.ramIndex
fileIndex=/Users/dennisluxen/Downloads/berlin-latest.osrm.fileIndex
namesData=/Users/dennisluxen/Downloads/berlin-latest.osrm.names
timestamp=/Users/dennisluxen/Downloads/berlin-latest.osrm.timestamp

View File

@ -21,7 +21,6 @@ or see http://www.gnu.org/licenses/agpl.txt.
#ifndef TYPEDEFS_H_
#define TYPEDEFS_H_
#include <cmath>
#include <climits>
#include <cstdlib>