Merge branch 'feature/roundabout4bikes' of https://github.com/svenluzar/Project-OSRM
This commit is contained in:
commit
111e68831e
2
.gitignore
vendored
2
.gitignore
vendored
@ -36,6 +36,7 @@ Thumbs.db
|
||||
# build related files #
|
||||
#######################
|
||||
/build/
|
||||
/Util/UUID.cpp
|
||||
|
||||
# Eclipse related files #
|
||||
#########################
|
||||
@ -72,6 +73,7 @@ stxxl.errlog
|
||||
/osrm-extract
|
||||
/osrm-routed
|
||||
/osrm-prepare
|
||||
/osrm-cli
|
||||
/nohup.out
|
||||
|
||||
# Sandbox folder #
|
||||
|
@ -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);
|
||||
|
@ -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.
|
||||
|
@ -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_ */
|
||||
|
@ -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 {
|
||||
|
@ -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_ */
|
||||
|
@ -1,22 +1,52 @@
|
||||
cmake_minimum_required(VERSION 2.6)
|
||||
project(OSRM)
|
||||
include(FindPackageHandleStandardArgs)
|
||||
|
||||
TRY_RUN(SHARED_LIBRARY_PATH_TYPE SHARED_LIBRARY_PATH_INFO_COMPILED ${PROJECT_BINARY_DIR}/CMakeTmp ${PROJECT_SOURCE_DIR}/cmake/size.cpp OUTPUT_VARIABLE IS_64_SYSTEM)
|
||||
if(IS_64_SYSTEM)
|
||||
message(STATUS "System supports 64 bits.")
|
||||
set( HAS64BITS 1 )
|
||||
else(IS_64_SYSTEM)
|
||||
MESSAGE(WARNING "Compiling on a 32 bit system is unsupported!")
|
||||
set( HAS64BITS 0 )
|
||||
endif(IS_64_SYSTEM)
|
||||
|
||||
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${CMAKE_CURRENT_SOURCE_DIR}/cmake)
|
||||
|
||||
add_custom_command(OUTPUT ${CMAKE_SOURCE_DIR}/Util/UUID.cpp UUID.cpp.alwaysbuild
|
||||
COMMAND ${CMAKE_COMMAND} -P
|
||||
${CMAKE_SOURCE_DIR}/cmake/UUID-Config.cmake
|
||||
DEPENDS
|
||||
${CMAKE_SOURCE_DIR}/Util/UUID.cpp.in
|
||||
${CMAKE_SOURCE_DIR}/cmake/UUID-Config.cmake
|
||||
COMMENT "Configuring UUID.cpp"
|
||||
VERBATIM)
|
||||
|
||||
add_custom_target(UUIDConfigure DEPENDS ${CMAKE_SOURCE_DIR}/Util/UUID.cpp )
|
||||
|
||||
set(BOOST_COMPONENTS filesystem regex system thread)
|
||||
|
||||
file(GLOB ExtractorGlob Extractor/*.cpp)
|
||||
set(ExtractorSources extractor.cpp ${ExtractorGlob})
|
||||
add_executable(osrm-extract ${ExtractorSources})
|
||||
add_executable(osrm-extract ${ExtractorSources} )
|
||||
|
||||
file(GLOB PrepareGlob Contractor/*.cpp)
|
||||
set(PrepareSources createHierarchy.cpp ${PrepareGlob})
|
||||
add_executable(osrm-prepare ${PrepareSources})
|
||||
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})
|
||||
add_library(UUID STATIC Util/UUID.cpp)
|
||||
add_dependencies( UUID UUIDConfigure )
|
||||
|
||||
# Check the release mode
|
||||
if(NOT CMAKE_BUILD_TYPE MATCHES Debug)
|
||||
set(CMAKE_BUILD_TYPE Release)
|
||||
@ -55,25 +85,39 @@ 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-extract ${Boost_LIBRARIES} )
|
||||
target_link_libraries( osrm-prepare ${Boost_LIBRARIES} )
|
||||
target_link_libraries( osrm-routed ${Boost_LIBRARIES} )
|
||||
|
||||
IF( APPLE )
|
||||
target_link_libraries( OSRM ${Boost_LIBRARIES} UUID )
|
||||
ELSE( APPLE )
|
||||
target_link_libraries( OSRM ${Boost_LIBRARIES} )
|
||||
ENDIF( APPLE )
|
||||
target_link_libraries( osrm-extract ${Boost_LIBRARIES} UUID )
|
||||
target_link_libraries( osrm-prepare ${Boost_LIBRARIES} UUID )
|
||||
target_link_libraries( osrm-routed ${Boost_LIBRARIES} OSRM UUID )
|
||||
|
||||
find_package ( BZip2 REQUIRED )
|
||||
include_directories(${BZIP_INCLUDE_DIRS})
|
||||
target_link_libraries (osrm-extract ${BZIP2_LIBRARIES})
|
||||
|
||||
find_package( ZLIB REQUIRED )
|
||||
include_directories(${ZLIB_INCLUDE_DIRS})
|
||||
target_link_libraries (osrm-extract ${ZLIB_LIBRARY})
|
||||
target_link_libraries (osrm-routed ${ZLIB_LIBRARY})
|
||||
|
||||
find_package( Threads REQUIRED )
|
||||
target_link_libraries (osrm-extract ${Threads_LIBRARY})
|
||||
|
||||
find_package( Lua51 REQUIRED )
|
||||
include_directories(${LUA_INCLUDE_DIR})
|
||||
target_link_libraries( osrm-extract ${LUA_LIBRARY} )
|
||||
target_link_libraries( osrm-prepare ${LUA_LIBRARY} )
|
||||
find_package( LuaJIT )
|
||||
IF( NOT APPLE AND 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 )
|
||||
include_directories(${LUA_INCLUDE_DIR})
|
||||
target_link_libraries( osrm-extract ${LUA_LIBRARY} )
|
||||
target_link_libraries( osrm-prepare ${LUA_LIBRARY} )
|
||||
ENDIF( NOT APPLE AND LUAJIT_INCLUDE_DIR AND LUAJIT_LIBRARIES )
|
||||
|
||||
find_package( LibXml2 REQUIRED )
|
||||
include_directories(${LIBXML2_INCLUDE_DIR})
|
||||
@ -91,6 +135,7 @@ target_link_libraries (osrm-prepare ${PROTOBUF_LIBRARY})
|
||||
|
||||
find_package( STXXL REQUIRED )
|
||||
include_directories(${STXXL_INCLUDE_DIR})
|
||||
target_link_libraries (OSRM ${STXXL_LIBRARY})
|
||||
target_link_libraries (osrm-extract ${STXXL_LIBRARY})
|
||||
target_link_libraries (osrm-prepare ${STXXL_LIBRARY})
|
||||
|
||||
@ -105,7 +150,10 @@ if(WITH_TOOLS)
|
||||
if(GDAL_FOUND)
|
||||
add_executable(osrm-components Tools/componentAnalysis.cpp)
|
||||
include_directories(${GDAL_INCLUDE_DIR})
|
||||
target_link_libraries( osrm-components ${GDAL_LIBRARIES} )
|
||||
target_link_libraries( osrm-components ${Boost_LIBRARIES} )
|
||||
target_link_libraries(
|
||||
osrm-components ${GDAL_LIBRARIES} ${Boost_LIBRARIES} UUID
|
||||
)
|
||||
endif(GDAL_FOUND)
|
||||
add_executable ( osrm-cli Tools/simpleclient.cpp )
|
||||
target_link_libraries( osrm-cli ${Boost_LIBRARIES} OSRM UUID )
|
||||
endif(WITH_TOOLS)
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -18,8 +18,6 @@
|
||||
or see http://www.gnu.org/licenses/agpl.txt.
|
||||
*/
|
||||
|
||||
#include <boost/foreach.hpp>
|
||||
|
||||
#include "TemporaryStorage.h"
|
||||
|
||||
TemporaryStorage::TemporaryStorage() {
|
||||
|
@ -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>
|
||||
|
@ -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;
|
||||
|
@ -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_ */
|
||||
|
@ -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_ */
|
@ -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_ */
|
@ -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 {
|
||||
|
@ -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"
|
||||
@ -31,9 +30,9 @@ or see http://www.gnu.org/licenses/agpl.txt.
|
||||
#include <boost/assert.hpp>
|
||||
#include <boost/noncopyable.hpp>
|
||||
|
||||
#include <fstream>
|
||||
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
typedef EdgeBasedGraphFactory::EdgeBasedNode RTreeLeaf;
|
||||
@ -41,10 +40,14 @@ typedef EdgeBasedGraphFactory::EdgeBasedNode RTreeLeaf;
|
||||
class NodeInformationHelpDesk : boost::noncopyable{
|
||||
public:
|
||||
NodeInformationHelpDesk(
|
||||
const char* ramIndexInput,
|
||||
const char* fileIndexInput,
|
||||
const std::string & ramIndexInput,
|
||||
const std::string & fileIndexInput,
|
||||
const std::string & nodes_filename,
|
||||
const std::string & edges_filename,
|
||||
const unsigned number_of_nodes,
|
||||
const unsigned crc) : number_of_nodes(number_of_nodes), checkSum(crc) {
|
||||
const unsigned check_sum
|
||||
) : number_of_nodes(number_of_nodes), check_sum(check_sum)
|
||||
{
|
||||
read_only_rtree = new StaticRTree<RTreeLeaf>(
|
||||
ramIndexInput,
|
||||
fileIndexInput
|
||||
@ -53,6 +56,8 @@ public:
|
||||
0 == coordinateVector.size(),
|
||||
"Coordinate vector not empty"
|
||||
);
|
||||
|
||||
LoadNodesAndEdges(nodes_filename, edges_filename);
|
||||
}
|
||||
|
||||
//Todo: Shared memory mechanism
|
||||
@ -60,38 +65,6 @@ public:
|
||||
delete read_only_rtree;
|
||||
}
|
||||
|
||||
void initNNGrid(
|
||||
std::ifstream& nodesInstream,
|
||||
std::ifstream& edgesInStream
|
||||
) {
|
||||
DEBUG("Loading node data");
|
||||
NodeInfo b;
|
||||
while(!nodesInstream.eof()) {
|
||||
nodesInstream.read((char *)&b, sizeof(NodeInfo));
|
||||
coordinateVector.push_back(_Coordinate(b.lat, b.lon));
|
||||
}
|
||||
std::vector<_Coordinate>(coordinateVector).swap(coordinateVector);
|
||||
nodesInstream.close();
|
||||
|
||||
DEBUG("Loading edge data");
|
||||
unsigned numberOfOrigEdges(0);
|
||||
edgesInStream.read((char*)&numberOfOrigEdges, sizeof(unsigned));
|
||||
origEdgeData_viaNode.resize(numberOfOrigEdges);
|
||||
origEdgeData_nameID.resize(numberOfOrigEdges);
|
||||
origEdgeData_turnInstruction.resize(numberOfOrigEdges);
|
||||
|
||||
OriginalEdgeData deserialized_originalEdgeData;
|
||||
for(unsigned i = 0; i < numberOfOrigEdges; ++i) {
|
||||
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;
|
||||
}
|
||||
edgesInStream.close();
|
||||
DEBUG("Loaded " << numberOfOrigEdges << " orig edges");
|
||||
DEBUG("Opening NN indices");
|
||||
}
|
||||
|
||||
inline int getLatitudeOfNode(const unsigned id) const {
|
||||
const NodeID node = origEdgeData_viaNode.at(id);
|
||||
return coordinateVector.at(node).lat;
|
||||
@ -124,7 +97,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;
|
||||
}
|
||||
@ -142,10 +118,50 @@ public:
|
||||
}
|
||||
|
||||
inline unsigned GetCheckSum() const {
|
||||
return checkSum;
|
||||
return check_sum;
|
||||
}
|
||||
|
||||
private:
|
||||
void LoadNodesAndEdges(
|
||||
const std::string & nodes_file,
|
||||
const std::string & edges_file
|
||||
) {
|
||||
std::ifstream nodes_input_stream(nodes_file.c_str(), std::ios::binary);
|
||||
if(!nodes_input_stream) { ERR(nodes_file << " not found"); }
|
||||
std::ifstream edges_input_stream(edges_file.c_str(), std::ios::binary);
|
||||
if(!edges_input_stream) { ERR(edges_file << " not found"); }
|
||||
|
||||
DEBUG("Loading node data");
|
||||
NodeInfo b;
|
||||
while(!nodes_input_stream.eof()) {
|
||||
nodes_input_stream.read((char *)&b, sizeof(NodeInfo));
|
||||
coordinateVector.push_back(_Coordinate(b.lat, b.lon));
|
||||
}
|
||||
std::vector<_Coordinate>(coordinateVector).swap(coordinateVector);
|
||||
nodes_input_stream.close();
|
||||
|
||||
DEBUG("Loading edge data");
|
||||
unsigned numberOfOrigEdges(0);
|
||||
edges_input_stream.read((char*)&numberOfOrigEdges, sizeof(unsigned));
|
||||
origEdgeData_viaNode.resize(numberOfOrigEdges);
|
||||
origEdgeData_nameID.resize(numberOfOrigEdges);
|
||||
origEdgeData_turnInstruction.resize(numberOfOrigEdges);
|
||||
|
||||
OriginalEdgeData deserialized_originalEdgeData;
|
||||
for(unsigned i = 0; i < numberOfOrigEdges; ++i) {
|
||||
edges_input_stream.read(
|
||||
(char*)&(deserialized_originalEdgeData),
|
||||
sizeof(OriginalEdgeData)
|
||||
);
|
||||
origEdgeData_viaNode[i] = deserialized_originalEdgeData.viaNode;
|
||||
origEdgeData_nameID[i] = deserialized_originalEdgeData.nameID;
|
||||
origEdgeData_turnInstruction[i] = deserialized_originalEdgeData.turnInstruction;
|
||||
}
|
||||
edges_input_stream.close();
|
||||
DEBUG("Loaded " << numberOfOrigEdges << " orig edges");
|
||||
DEBUG("Opening NN indices");
|
||||
}
|
||||
|
||||
std::vector<_Coordinate> coordinateVector;
|
||||
std::vector<NodeID> origEdgeData_viaNode;
|
||||
std::vector<unsigned> origEdgeData_nameID;
|
||||
@ -153,7 +169,7 @@ private:
|
||||
|
||||
StaticRTree<EdgeBasedGraphFactory::EdgeBasedNode> * read_only_rtree;
|
||||
const unsigned number_of_nodes;
|
||||
const unsigned checkSum;
|
||||
const unsigned check_sum;
|
||||
};
|
||||
|
||||
#endif /*NODEINFORMATIONHELPDESK_H_*/
|
||||
|
@ -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:
|
||||
|
@ -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_ */
|
||||
|
@ -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;
|
||||
|
@ -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 {
|
||||
|
@ -45,6 +45,7 @@ or see http://www.gnu.org/licenses/agpl.txt.
|
||||
#include <algorithm>
|
||||
#include <fstream>
|
||||
#include <queue>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
//tuning parameters
|
||||
@ -215,8 +216,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 +231,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 +261,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;
|
||||
}
|
||||
@ -264,26 +276,24 @@ private:
|
||||
std::vector<TreeNode> m_search_tree;
|
||||
uint64_t m_element_count;
|
||||
|
||||
std::string m_leaf_node_filename;
|
||||
const 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 std::string tree_node_filename,
|
||||
const std::string 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);
|
||||
std::ofstream leaf_node_file(leaf_node_filename.c_str(), 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
|
||||
@ -388,7 +386,7 @@ public:
|
||||
}
|
||||
|
||||
//open tree file
|
||||
std::ofstream tree_node_file(tree_node_filename, std::ios::binary);
|
||||
std::ofstream tree_node_file(tree_node_filename.c_str(), std::ios::binary);
|
||||
uint32_t size_of_tree = m_search_tree.size();
|
||||
BOOST_ASSERT_MSG(0 < size_of_tree, "tree empty");
|
||||
tree_node_file.write((char *)&size_of_tree, sizeof(uint32_t));
|
||||
@ -396,38 +394,16 @@ 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
|
||||
explicit StaticRTree(
|
||||
const char * node_filename,
|
||||
const char * leaf_filename
|
||||
const std::string & node_filename,
|
||||
const std::string & leaf_filename
|
||||
) : m_leaf_node_filename(leaf_filename) {
|
||||
//INFO("Loading nodes: " << node_filename);
|
||||
//INFO("opening leafs: " << leaf_filename);
|
||||
//open tree node file and load into RAM.
|
||||
std::ifstream tree_node_file(node_filename, std::ios::binary);
|
||||
std::ifstream tree_node_file(node_filename.c_str(), std::ios::binary);
|
||||
uint32_t tree_size = 0;
|
||||
tree_node_file.read((char*)&tree_size, sizeof(uint32_t));
|
||||
//INFO("reading " << tree_size << " tree nodes in " << (sizeof(TreeNode)*tree_size) << " bytes");
|
||||
@ -436,7 +412,7 @@ public:
|
||||
tree_node_file.close();
|
||||
|
||||
//open leaf node file and store thread specific pointer
|
||||
std::ifstream leaf_node_file(leaf_filename, std::ios::binary);
|
||||
std::ifstream leaf_node_file(leaf_filename.c_str(), std::ios::binary);
|
||||
leaf_node_file.read((char*)&m_element_count, sizeof(uint64_t));
|
||||
leaf_node_file.close();
|
||||
|
||||
@ -557,11 +533,20 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
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
|
||||
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., 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 +561,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 +628,6 @@ public:
|
||||
¤t_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 +717,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()) {
|
||||
|
@ -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:
|
||||
|
@ -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) {}
|
||||
|
@ -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;
|
||||
|
@ -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 */
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
@ -121,6 +121,7 @@ void ExtractionContainers::PrepareData(const std::string & outputFileName, const
|
||||
//serialize restrictions
|
||||
std::ofstream restrictionsOutstream;
|
||||
restrictionsOutstream.open(restrictionsFileName.c_str(), std::ios::binary);
|
||||
restrictionsOutstream.write((char*)&uuid, sizeof(UUID));
|
||||
restrictionsOutstream.write((char*)&usableRestrictionsCounter, sizeof(unsigned));
|
||||
for(restrictionsIT = restrictionsVector.begin(); restrictionsIT != restrictionsVector.end(); ++restrictionsIT) {
|
||||
if(UINT_MAX != restrictionsIT->restriction.fromNode && UINT_MAX != restrictionsIT->restriction.toNode) {
|
||||
@ -130,7 +131,8 @@ 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*)&uuid, sizeof(UUID));
|
||||
fout.write((char*)&usedNodeCounter, sizeof(unsigned));
|
||||
time = get_timestamp();
|
||||
std::cout << "[extractor] Confirming/Writing used nodes ... " << std::flush;
|
||||
@ -158,7 +160,7 @@ void ExtractionContainers::PrepareData(const std::string & outputFileName, const
|
||||
|
||||
std::cout << "[extractor] setting number of nodes ... " << std::flush;
|
||||
std::ios::pos_type positionInFile = fout.tellp();
|
||||
fout.seekp(std::ios::beg);
|
||||
fout.seekp(std::ios::beg+sizeof(UUID));
|
||||
fout.write((char*)&usedNodeCounter, sizeof(unsigned));
|
||||
fout.seekp(positionInFile);
|
||||
|
||||
@ -271,7 +273,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));
|
||||
|
@ -23,6 +23,7 @@
|
||||
|
||||
#include "ExtractorStructs.h"
|
||||
#include "../DataStructures/TimingUtil.h"
|
||||
#include "../Util/UUID.h"
|
||||
|
||||
#include <boost/foreach.hpp>
|
||||
#include <stxxl.h>
|
||||
@ -55,7 +56,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;
|
||||
@ -63,7 +64,7 @@ public:
|
||||
STXXLStringVector nameVector;
|
||||
STXXLRestrictionsVector restrictionsVector;
|
||||
STXXLWayIDStartEndVector wayStartEndVector;
|
||||
|
||||
const UUID uuid;
|
||||
};
|
||||
|
||||
#endif /* EXTRACTIONCONTAINERS_H_ */
|
||||
|
@ -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
|
||||
|
@ -12,26 +12,6 @@ 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
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
|
||||
@ -40,7 +20,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) {
|
||||
|
@ -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{
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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 {
|
||||
|
@ -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:
|
||||
|
@ -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");
|
||||
@ -130,13 +129,13 @@ _RawRestrictionContainer XMLParser::_ReadXMLRestriction() {
|
||||
xmlChar * type = xmlTextReaderGetAttribute( inputReader, ( const xmlChar* ) "type" );
|
||||
|
||||
if(xmlStrEqual(role, (const xmlChar *) "to") && xmlStrEqual(type, (const xmlChar *) "way")) {
|
||||
restriction.toWay = atoi((const char*) ref);
|
||||
restriction.toWay = stringToUint((const char*) ref);
|
||||
}
|
||||
if(xmlStrEqual(role, (const xmlChar *) "from") && xmlStrEqual(type, (const xmlChar *) "way")) {
|
||||
restriction.fromWay = atoi((const char*) ref);
|
||||
restriction.fromWay = stringToUint((const char*) ref);
|
||||
}
|
||||
if(xmlStrEqual(role, (const xmlChar *) "via") && xmlStrEqual(type, (const xmlChar *) "node")) {
|
||||
restriction.restriction.viaNode = atoi((const char*) ref);
|
||||
restriction.restriction.viaNode = stringToUint((const char*) ref);
|
||||
}
|
||||
|
||||
if(NULL != type) {
|
||||
@ -177,7 +176,7 @@ ExtractionWay XMLParser::_ReadXMLWay() {
|
||||
|
||||
if ( depth == childDepth && childType == 15 && xmlStrEqual( childName, ( const xmlChar* ) "way" ) == 1 ) {
|
||||
xmlChar* id = xmlTextReaderGetAttribute( inputReader, ( const xmlChar* ) "id" );
|
||||
way.id = atoi((char*)id);
|
||||
way.id = stringToUint((char*)id);
|
||||
xmlFree(id);
|
||||
xmlFree( childName );
|
||||
break;
|
||||
@ -203,7 +202,7 @@ ExtractionWay XMLParser::_ReadXMLWay() {
|
||||
} else if ( xmlStrEqual( childName, ( const xmlChar* ) "nd" ) == 1 ) {
|
||||
xmlChar* ref = xmlTextReaderGetAttribute( inputReader, ( const xmlChar* ) "ref" );
|
||||
if ( ref != NULL ) {
|
||||
way.path.push_back( atoi(( const char* ) ref ) );
|
||||
way.path.push_back( stringToUint(( const char* ) ref ) );
|
||||
xmlFree( ref );
|
||||
}
|
||||
}
|
||||
@ -228,7 +227,7 @@ ImportNode XMLParser::_ReadXMLNode() {
|
||||
}
|
||||
attribute = xmlTextReaderGetAttribute( inputReader, ( const xmlChar* ) "id" );
|
||||
if ( attribute != NULL ) {
|
||||
node.id = atoi(( const char* ) attribute );
|
||||
node.id = stringToUint(( const char* ) attribute );
|
||||
xmlFree( attribute );
|
||||
}
|
||||
|
||||
|
@ -21,10 +21,12 @@
|
||||
#ifndef XMLPARSER_H_
|
||||
#define XMLPARSER_H_
|
||||
|
||||
#include "BaseParser.h"
|
||||
#include "../Util/StringUtil.h"
|
||||
#include "../typedefs.h"
|
||||
|
||||
#include <libxml/xmlreader.h>
|
||||
|
||||
#include "../typedefs.h"
|
||||
#include "BaseParser.h"
|
||||
|
||||
class XMLParser : public BaseParser {
|
||||
public:
|
||||
|
66
Library/OSRM.cpp
Normal file
66
Library/OSRM.cpp
Normal 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
66
Library/OSRM.h
Normal 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
|
@ -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() { }
|
||||
|
@ -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"); }
|
||||
|
||||
|
@ -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.
|
||||
*/
|
||||
|
@ -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_ */
|
@ -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;
|
||||
|
@ -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) {
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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 {
|
||||
|
||||
|
@ -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);
|
||||
@ -57,19 +58,23 @@ QueryObjectsStorage::QueryObjectsStorage(
|
||||
getline(timestampInStream, timestamp);
|
||||
timestampInStream.close();
|
||||
}
|
||||
if(!timestamp.length())
|
||||
if(!timestamp.length()) {
|
||||
timestamp = "n/a";
|
||||
if(25 < timestamp.length())
|
||||
}
|
||||
if(25 < timestamp.length()) {
|
||||
timestamp.resize(25);
|
||||
}
|
||||
|
||||
INFO("Loading auxiliary information");
|
||||
//Init nearest neighbor data structure
|
||||
std::ifstream nodesInStream(nodesPath.c_str(), std::ios::binary);
|
||||
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->initNNGrid(nodesInStream, edgesInStream);
|
||||
nodeHelpDesk = new NodeInformationHelpDesk(
|
||||
ramIndexPath,
|
||||
fileIndexPath,
|
||||
nodesPath,
|
||||
edgesPath,
|
||||
n,
|
||||
checkSum
|
||||
);
|
||||
|
||||
//deserialize street name list
|
||||
INFO("Loading names index");
|
||||
@ -77,7 +82,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 +92,6 @@ QueryObjectsStorage::QueryObjectsStorage(
|
||||
names.push_back(buf);
|
||||
}
|
||||
std::vector<std::string>(names).swap(names);
|
||||
hsgrInStream.close();
|
||||
namesInStream.close();
|
||||
INFO("All query data structures loaded");
|
||||
}
|
||||
|
@ -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();
|
||||
};
|
||||
|
@ -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 += " ";
|
||||
}
|
||||
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
|
||||
|
@ -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
|
||||
|
@ -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_ */
|
@ -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);
|
||||
}
|
||||
};
|
||||
|
@ -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 DynamicGraph<EdgeData>::InputEdge InputEdge;
|
||||
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
86
Tools/simpleclient.cpp
Normal 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;
|
||||
}
|
@ -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)
|
||||
|
@ -25,6 +25,7 @@ or see http://www.gnu.org/licenses/agpl.txt.
|
||||
#include "../DataStructures/ImportEdge.h"
|
||||
#include "../DataStructures/NodeCoords.h"
|
||||
#include "../DataStructures/Restriction.h"
|
||||
#include "../Util/UUID.h"
|
||||
#include "../typedefs.h"
|
||||
|
||||
#include <boost/assert.hpp>
|
||||
@ -49,13 +50,31 @@ struct _ExcessRemover {
|
||||
};
|
||||
|
||||
template<typename EdgeT>
|
||||
NodeID readBinaryOSRMGraphFromStream(std::istream &in, std::vector<EdgeT>& edgeList, std::vector<NodeID> &bollardNodes, std::vector<NodeID> &trafficLightNodes, std::vector<NodeInfo> * int2ExtNodeMap, std::vector<_Restriction> & inputRestrictions) {
|
||||
NodeID readBinaryOSRMGraphFromStream(
|
||||
std::istream &in,
|
||||
std::vector<EdgeT>& edgeList,
|
||||
std::vector<NodeID> &bollardNodes,
|
||||
std::vector<NodeID> &trafficLightNodes,
|
||||
std::vector<NodeInfo> * int2ExtNodeMap,
|
||||
std::vector<_Restriction> & inputRestrictions
|
||||
) {
|
||||
const UUID uuid_orig;
|
||||
UUID uuid_loaded;
|
||||
in.read((char *) &uuid_loaded, sizeof(UUID));
|
||||
|
||||
if( !uuid_loaded.TestGraphUtil(uuid_orig) ) {
|
||||
WARN(
|
||||
".osrm was prepared with different build.\n"
|
||||
"Reprocess to get rid of this warning."
|
||||
)
|
||||
}
|
||||
|
||||
NodeID n, source, target;
|
||||
EdgeID m;
|
||||
short dir;// direction (0 = open, 1 = forward, 2+ = open)
|
||||
ExternalNodeMap ext2IntNodeMap;
|
||||
in.read((char*)&n, sizeof(NodeID));
|
||||
DEBUG("Importing n = " << n << " nodes ");
|
||||
INFO("Importing n = " << n << " nodes ");
|
||||
_Node node;
|
||||
for (NodeID i=0; i<n; ++i) {
|
||||
in.read((char*)&node, sizeof(_Node));
|
||||
@ -72,7 +91,7 @@ NodeID readBinaryOSRMGraphFromStream(std::istream &in, std::vector<EdgeT>& edgeL
|
||||
std::vector<NodeID>(trafficLightNodes).swap(trafficLightNodes);
|
||||
|
||||
in.read((char*)&m, sizeof(unsigned));
|
||||
DEBUG(" and " << m << " edges ");
|
||||
INFO(" and " << m << " edges ");
|
||||
for(unsigned i = 0; i < inputRestrictions.size(); ++i) {
|
||||
ExternalNodeMap::iterator intNodeID = ext2IntNodeMap.find(inputRestrictions[i].fromNode);
|
||||
if( intNodeID == ext2IntNodeMap.end()) {
|
||||
@ -202,7 +221,7 @@ NodeID readDTMPGraphFromStream(std::istream &in, std::vector<EdgeT>& edgeList, s
|
||||
ExternalNodeMap ext2IntNodeMap;
|
||||
in >> n;
|
||||
DEBUG("Importing n = " << n << " nodes ");
|
||||
for (NodeID i=0; i<n;++i) {
|
||||
for (NodeID i=0; i<n; ++i) {
|
||||
in >> id >> ycoord >> xcoord;
|
||||
int2ExtNodeMap->push_back(NodeInfo(xcoord, ycoord, id));
|
||||
ext2IntNodeMap.insert(std::make_pair(id, i));
|
||||
@ -219,9 +238,9 @@ NodeID readDTMPGraphFromStream(std::istream &in, std::vector<EdgeT>& edgeList, s
|
||||
int length;
|
||||
in >> source >> target >> length >> dir >> speedType;
|
||||
|
||||
if(dir == 3)
|
||||
if(dir == 3) {
|
||||
dir = 0;
|
||||
|
||||
}
|
||||
switch(speedType) {
|
||||
case 1:
|
||||
weight = 130;
|
||||
@ -271,8 +290,9 @@ NodeID readDTMPGraphFromStream(std::istream &in, std::vector<EdgeT>& edgeList, s
|
||||
}
|
||||
|
||||
weight = length*weight/3.6;
|
||||
if(speedType == 13)
|
||||
if(speedType == 13) {
|
||||
weight = length;
|
||||
}
|
||||
assert(length > 0);
|
||||
assert(weight > 0);
|
||||
if(dir <0 || dir > 2)
|
||||
@ -281,8 +301,12 @@ NodeID readDTMPGraphFromStream(std::istream &in, std::vector<EdgeT>& edgeList, s
|
||||
|
||||
bool forward = true;
|
||||
bool backward = true;
|
||||
if (dir == 1) backward = false;
|
||||
if (dir == 2) forward = false;
|
||||
if (dir == 1) {
|
||||
backward = false;
|
||||
}
|
||||
if (dir == 2) {
|
||||
forward = false;
|
||||
}
|
||||
|
||||
if(length == 0) { ERR("loaded null length edge"); }
|
||||
|
||||
@ -359,19 +383,43 @@ NodeID readDDSGGraphFromStream(std::istream &in, std::vector<EdgeT>& edgeList, s
|
||||
}
|
||||
|
||||
template<typename NodeT, typename EdgeT>
|
||||
unsigned readHSGRFromStream(std::istream &in, std::vector<NodeT>& nodeList, std::vector<EdgeT> & edgeList, unsigned * checkSum) {
|
||||
unsigned numberOfNodes = 0;
|
||||
in.read((char*) checkSum, sizeof(unsigned));
|
||||
in.read((char*) & numberOfNodes, sizeof(unsigned));
|
||||
nodeList.resize(numberOfNodes + 1);
|
||||
in.read((char*) &(nodeList[0]), numberOfNodes*sizeof(NodeT));
|
||||
unsigned readHSGRFromStream(
|
||||
std::istream &hsgr_input_stream,
|
||||
std::vector<NodeT> & node_list,
|
||||
std::vector<EdgeT> & edge_list,
|
||||
unsigned * check_sum
|
||||
) {
|
||||
UUID uuid_loaded, uuid_orig;
|
||||
hsgr_input_stream.read((char *)&uuid_loaded, sizeof(UUID));
|
||||
if( !uuid_loaded.TestGraphUtil(uuid_orig) ) {
|
||||
WARN(
|
||||
".hsgr was prepared with different build.\n"
|
||||
"Reprocess to get rid of this warning."
|
||||
)
|
||||
}
|
||||
|
||||
unsigned numberOfEdges = 0;
|
||||
in.read((char*) &numberOfEdges, sizeof(unsigned));
|
||||
edgeList.resize(numberOfEdges);
|
||||
in.read((char*) &(edgeList[0]), numberOfEdges*sizeof(EdgeT));
|
||||
unsigned number_of_nodes = 0;
|
||||
hsgr_input_stream.read((char*) check_sum, sizeof(unsigned));
|
||||
hsgr_input_stream.read((char*) & number_of_nodes, sizeof(unsigned));
|
||||
node_list.resize(number_of_nodes + 1);
|
||||
hsgr_input_stream.read(
|
||||
(char*) &(node_list[0]),
|
||||
number_of_nodes*sizeof(NodeT)
|
||||
);
|
||||
|
||||
return numberOfNodes;
|
||||
unsigned number_of_edges = 0;
|
||||
hsgr_input_stream.read(
|
||||
(char*) &number_of_edges,
|
||||
sizeof(unsigned)
|
||||
);
|
||||
|
||||
edge_list.resize(number_of_edges);
|
||||
hsgr_input_stream.read(
|
||||
(char*) &(edge_list[0]),
|
||||
number_of_edges*sizeof(EdgeT)
|
||||
);
|
||||
|
||||
return number_of_nodes;
|
||||
}
|
||||
|
||||
#endif // GRAPHLOADER_H
|
||||
|
@ -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);
|
||||
|
@ -25,7 +25,6 @@ or see http://www.gnu.org/licenses/agpl.txt.
|
||||
|
||||
#include <string>
|
||||
|
||||
|
||||
#ifdef __linux__
|
||||
#include <cxxabi.h>
|
||||
#include <execinfo.h>
|
||||
|
@ -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 {
|
||||
|
@ -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 */
|
||||
|
@ -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 >
|
||||
@ -63,23 +62,63 @@ static inline char* printInt( char* buffer, int value ) {
|
||||
}
|
||||
|
||||
static inline void intToString(const int value, std::string & output) {
|
||||
// The largest 32-bit integer is 4294967295, that is 10 chars
|
||||
// On the safe side, add 1 for sign, and 1 for trailing zero
|
||||
output.clear();
|
||||
std::back_insert_iterator<std::string> sink(output);
|
||||
boost::spirit::karma::generate(sink, boost::spirit::karma::int_, value);
|
||||
}
|
||||
|
||||
static inline void int64ToString(const int64_t value, std::string & output) {
|
||||
output.clear();
|
||||
std::back_insert_iterator<std::string> sink(output);
|
||||
boost::spirit::karma::generate(sink, boost::spirit::karma::long_long, value);
|
||||
}
|
||||
|
||||
static inline int stringToInt(const std::string& input) {
|
||||
std::string::const_iterator realBeginOfNumber = input.begin();
|
||||
std::string::const_iterator first_digit = input.begin();
|
||||
//Delete any trailing white-spaces
|
||||
while(realBeginOfNumber != input.end() && std::isspace(*realBeginOfNumber))
|
||||
++realBeginOfNumber;
|
||||
int value = 0; // 2
|
||||
boost::spirit::qi::parse(realBeginOfNumber, input.end(), boost::spirit::int_, value); // 3
|
||||
while(first_digit != input.end() && std::isspace(*first_digit)) {
|
||||
++first_digit;
|
||||
}
|
||||
int value = 0;
|
||||
boost::spirit::qi::parse(
|
||||
first_digit,
|
||||
input.end(),
|
||||
boost::spirit::int_, value
|
||||
);
|
||||
return value;
|
||||
}
|
||||
|
||||
static inline unsigned stringToUint(const std::string& input) {
|
||||
std::string::const_iterator first_digit = input.begin();
|
||||
//Delete any trailing white-spaces
|
||||
while(first_digit != input.end() && std::isspace(*first_digit)) {
|
||||
++first_digit;
|
||||
}
|
||||
int value = 0;
|
||||
boost::spirit::qi::parse(
|
||||
first_digit,
|
||||
input.end(),
|
||||
boost::spirit::uint_, value
|
||||
);
|
||||
return value;
|
||||
}
|
||||
|
||||
static inline uint64_t stringToInt64(const std::string& input) {
|
||||
std::string::const_iterator first_digit = input.begin();
|
||||
//Delete any trailing white-spaces
|
||||
while(first_digit != input.end() && std::isspace(*first_digit)) {
|
||||
++first_digit;
|
||||
}
|
||||
uint64_t value = 0;
|
||||
boost::spirit::qi::parse(
|
||||
first_digit,
|
||||
input.end(),
|
||||
boost::spirit::long_long, value
|
||||
);
|
||||
return value;
|
||||
}
|
||||
|
||||
|
||||
static inline void doubleToString(const double value, std::string & output){
|
||||
output.clear();
|
||||
std::back_insert_iterator<std::string> sink(output);
|
||||
@ -94,32 +133,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);
|
||||
}
|
||||
|
95
Util/UUID.cpp.in
Normal file
95
Util/UUID.cpp.in
Normal file
@ -0,0 +1,95 @@
|
||||
/*
|
||||
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.
|
||||
*/
|
||||
|
||||
#include "UUID.h"
|
||||
|
||||
#cmakedefine01 HAS64BITS
|
||||
#cmakedefine MD5PREPARE "${MD5PREPARE}"
|
||||
#cmakedefine MD5RTREE "${MD5RTREE}"
|
||||
#cmakedefine MD5NODEINFO "${MD5NODEINFO}"
|
||||
#cmakedefine MD5GRAPH "${MD5GRAPH}"
|
||||
#cmakedefine MD5OBJECTS "${MD5OBJECTS}"
|
||||
|
||||
UUID::UUID() : magic_number(1297240911) {
|
||||
boost::uuids::name_generator gen(named_uuid);
|
||||
std::string temp_string(__DATE__);
|
||||
temp_string += __TIME__;
|
||||
|
||||
std::copy(MD5PREPARE, MD5PREPARE+strlen(MD5PREPARE), md5_prepare);
|
||||
temp_string += md5_prepare;
|
||||
std::copy(MD5RTREE, MD5RTREE+32, md5_tree);
|
||||
temp_string += md5_tree;
|
||||
std::copy(MD5NODEINFO, MD5NODEINFO+32, md5_nodeinfo);
|
||||
temp_string += md5_nodeinfo;
|
||||
std::copy(MD5GRAPH, MD5GRAPH+32, md5_graph);
|
||||
temp_string += md5_graph;
|
||||
std::copy(MD5OBJECTS, MD5OBJECTS+32, md5_objects);
|
||||
temp_string += md5_objects;
|
||||
|
||||
named_uuid = gen(temp_string);
|
||||
has_64_bits = HAS64BITS;
|
||||
}
|
||||
|
||||
UUID::~UUID() {
|
||||
|
||||
}
|
||||
|
||||
const boost::uuids::uuid & UUID::GetUUID() const {
|
||||
return named_uuid;
|
||||
}
|
||||
|
||||
const bool UUID::IsMagicNumberOK() const {
|
||||
return 1297240911 == magic_number;
|
||||
}
|
||||
|
||||
const bool UUID::TestGraphUtil(const UUID & other) const {
|
||||
if(!other.IsMagicNumberOK()) {
|
||||
ERR("hsgr input file misses magic number. Check or reprocess the file");
|
||||
}
|
||||
return std::equal(md5_graph, md5_graph+32, other.md5_graph);
|
||||
}
|
||||
|
||||
const bool UUID::TestPrepare(const UUID & other) const {
|
||||
if(!other.IsMagicNumberOK()) {
|
||||
ERR("extracted input file misses magic number. Check or reprocess the file");
|
||||
}
|
||||
return std::equal(md5_prepare, md5_prepare+32, other.md5_prepare);
|
||||
}
|
||||
|
||||
const bool UUID::TestRTree(const UUID & other) const {
|
||||
if(!other.IsMagicNumberOK()) {
|
||||
ERR("r-tree input file misses magic number. Check or reprocess the file");
|
||||
}
|
||||
return std::equal(md5_tree, md5_tree+32, other.md5_tree);
|
||||
}
|
||||
|
||||
const bool UUID::TestNodeInfo(const UUID & other) const {
|
||||
if(!other.IsMagicNumberOK()) {
|
||||
ERR("nodes file misses magic number. Check or reprocess the file");
|
||||
}
|
||||
return std::equal(md5_nodeinfo, md5_nodeinfo+32, other.md5_nodeinfo);
|
||||
}
|
||||
|
||||
const bool UUID::TestQueryObjects(const UUID & other) const {
|
||||
if(!other.IsMagicNumberOK()) {
|
||||
ERR("missing magic number. Check or reprocess the file");
|
||||
}
|
||||
return std::equal(md5_objects, md5_objects+32, other.md5_objects);
|
||||
}
|
62
Util/UUID.h
Normal file
62
Util/UUID.h
Normal file
@ -0,0 +1,62 @@
|
||||
/*
|
||||
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 UUID_H
|
||||
#define UUID_H
|
||||
|
||||
#include "../typedefs.h"
|
||||
|
||||
#include <boost/noncopyable.hpp>
|
||||
#include <boost/uuid/uuid.hpp> // uuid class
|
||||
#include <boost/uuid/uuid_generators.hpp> // generators
|
||||
#include <boost/uuid/uuid_io.hpp> // streaming operators etc.
|
||||
|
||||
#include <cstring>
|
||||
|
||||
#include <algorithm>
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
|
||||
//implements a singleton, i.e. there is one and only one conviguration object
|
||||
class UUID : boost::noncopyable {
|
||||
public:
|
||||
UUID();
|
||||
~UUID();
|
||||
const boost::uuids::uuid & GetUUID() const;
|
||||
const bool IsMagicNumberOK() const;
|
||||
const bool TestGraphUtil(const UUID & other) const;
|
||||
const bool TestPrepare(const UUID & other) const;
|
||||
const bool TestRTree(const UUID & other) const;
|
||||
const bool TestNodeInfo(const UUID & other) const;
|
||||
const bool TestQueryObjects(const UUID & other) const;
|
||||
private:
|
||||
const unsigned magic_number;
|
||||
char md5_prepare[33];
|
||||
char md5_tree[33];
|
||||
char md5_nodeinfo[33];
|
||||
char md5_graph[33];
|
||||
char md5_objects[33];
|
||||
|
||||
// initialize to {6ba7b810-9dad-11d1-80b4-00c04fd430c8}
|
||||
boost::uuids::uuid named_uuid;
|
||||
bool has_64_bits;
|
||||
};
|
||||
|
||||
#endif /* UUID_H */
|
86
cmake/FindLuaJIT.cmake
Normal file
86
cmake/FindLuaJIT.cmake
Normal file
@ -0,0 +1,86 @@
|
||||
# Locate Lua library
|
||||
# This module defines
|
||||
# LUAJIT_FOUND, if false, do not try to link to Lua
|
||||
# LUAJIT_LIBRARIES
|
||||
# LUAJIT_INCLUDE_DIR, where to find lua.h
|
||||
#
|
||||
# Note that the expected include convention is
|
||||
# #include "lua.h"
|
||||
# and not
|
||||
# #include <lua/lua.h>
|
||||
# This is because, the lua location is not standardized and may exist
|
||||
# in locations other than lua/
|
||||
|
||||
#=============================================================================
|
||||
# Copyright 2007-2009 Kitware, Inc.
|
||||
#
|
||||
# Distributed under the OSI-approved BSD License (the "License");
|
||||
# see accompanying file Copyright.txt for details.
|
||||
#
|
||||
# This software is distributed WITHOUT ANY WARRANTY; without even the
|
||||
# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
# See the License for more information.
|
||||
#=============================================================================
|
||||
# (To distributed this file outside of CMake, substitute the full
|
||||
# License text for the above reference.)
|
||||
#
|
||||
# ################
|
||||
# 2010 - modified for cronkite to find luajit instead of lua, as it was before.
|
||||
#
|
||||
|
||||
IF( NOT LUAJIT_FIND_QUIETLY )
|
||||
MESSAGE(STATUS "Looking for LuaJIT...")
|
||||
ENDIF()
|
||||
|
||||
FIND_PATH(LUAJIT_INCLUDE_DIR lua.h
|
||||
HINTS
|
||||
$ENV{LUAJIT_DIR}
|
||||
PATH_SUFFIXES include/luajit-2.0 include/luajit2.0 include/luajit include
|
||||
PATHS
|
||||
~/Library/Frameworks
|
||||
/Library/Frameworks
|
||||
/usr/local
|
||||
/usr
|
||||
/sw # Fink
|
||||
/opt/local # DarwinPorts
|
||||
/opt/csw # Blastwave
|
||||
/opt
|
||||
)
|
||||
|
||||
FIND_LIBRARY(LUAJIT_LIBRARY
|
||||
NAMES luajit-51 luajit-5.1 luajit
|
||||
HINTS
|
||||
$ENV{LUAJIT_DIR}
|
||||
PATH_SUFFIXES lib64 lib
|
||||
PATHS
|
||||
~/Library/Frameworks
|
||||
/Library/Frameworks
|
||||
/usr/local
|
||||
/usr
|
||||
/sw
|
||||
/opt/local
|
||||
/opt/csw
|
||||
/opt
|
||||
)
|
||||
|
||||
# include the math library for Unix
|
||||
IF(UNIX AND NOT APPLE)
|
||||
FIND_LIBRARY(LUAJIT_MATH_LIBRARY m)
|
||||
SET( LUAJIT_LIBRARIES "${LUAJIT_LIBRARY};${LUAJIT_MATH_LIBRARY}" CACHE STRING "Lua Libraries")
|
||||
# For Windows and Mac, don't need to explicitly include the math library
|
||||
ELSE(UNIX AND NOT APPLE)
|
||||
SET( LUAJIT_LIBRARIES "${LUAJIT_LIBRARY}" CACHE STRING "Lua Libraries")
|
||||
ENDIF(UNIX AND NOT APPLE)
|
||||
#ENDIF(LUAJIT_LIBRARY)
|
||||
|
||||
INCLUDE(FindPackageHandleStandardArgs)
|
||||
# handle the QUIETLY and REQUIRED arguments and set LUAJIT_FOUND to TRUE if
|
||||
# all listed variables are TRUE
|
||||
FIND_PACKAGE_HANDLE_STANDARD_ARGS(LuaJIT DEFAULT_MSG LUAJIT_LIBRARIES LUAJIT_INCLUDE_DIR)
|
||||
|
||||
IF( NOT LUAJIT_FIND_QUIETLY )
|
||||
IF( LUAJIT_FOUND )
|
||||
MESSAGE(STATUS "Found LuaJIT: ${LUAJIT_LIBRARY}" )
|
||||
ENDIF()
|
||||
ENDIF()
|
||||
MARK_AS_ADVANCED(LUAJIT_INCLUDE_DIR LUAJIT_LIBRARIES LUAJIT_LIBRARY LUAJIT_MATH_LIBRARY)
|
@ -27,7 +27,7 @@ FIND_PATH(LUABIND_INCLUDE_DIR luabind.hpp
|
||||
)
|
||||
|
||||
FIND_LIBRARY(LUABIND_LIBRARY
|
||||
NAMES luabind
|
||||
NAMES luabind luabind09
|
||||
HINTS
|
||||
$ENV{LUABIND_DIR}
|
||||
PATH_SUFFIXES lib64 lib
|
||||
|
@ -1,123 +0,0 @@
|
||||
# - Returns a version string from Git
|
||||
#
|
||||
# These functions force a re-configure on each git commit so that you can
|
||||
# trust the values of the variables in your build system.
|
||||
#
|
||||
# get_git_head_revision(<refspecvar> <hashvar> [<additional arguments to git describe> ...])
|
||||
#
|
||||
# Returns the refspec and sha hash of the current head revision
|
||||
#
|
||||
# git_describe(<var> [<additional arguments to git describe> ...])
|
||||
#
|
||||
# Returns the results of git describe on the source tree, and adjusting
|
||||
# the output so that it tests false if an error occurs.
|
||||
#
|
||||
# git_get_exact_tag(<var> [<additional arguments to git describe> ...])
|
||||
#
|
||||
# Returns the results of git describe --exact-match on the source tree,
|
||||
# and adjusting the output so that it tests false if there was no exact
|
||||
# matching tag.
|
||||
#
|
||||
# Requires CMake 2.6 or newer (uses the 'function' command)
|
||||
#
|
||||
# Original Author:
|
||||
# 2009-2010 Ryan Pavlik <rpavlik@iastate.edu> <abiryan@ryand.net>
|
||||
# http://academic.cleardefinition.com
|
||||
# Iowa State University HCI Graduate Program/VRAC
|
||||
#
|
||||
# Copyright Iowa State University 2009-2010.
|
||||
# Distributed under the Boost Software License, Version 1.0.
|
||||
# (See accompanying file LICENSE_1_0.txt or copy at
|
||||
# http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
if(__get_git_revision_description)
|
||||
return()
|
||||
endif()
|
||||
set(__get_git_revision_description YES)
|
||||
|
||||
# We must run the following at "include" time, not at function call time,
|
||||
# to find the path to this module rather than the path to a calling list file
|
||||
get_filename_component(_gitdescmoddir ${CMAKE_CURRENT_LIST_FILE} PATH)
|
||||
|
||||
function(get_git_head_revision _refspecvar _hashvar)
|
||||
set(GIT_PARENT_DIR "${CMAKE_SOURCE_DIR}")
|
||||
set(GIT_DIR "${GIT_PARENT_DIR}/.git")
|
||||
while(NOT EXISTS "${GIT_DIR}") # .git dir not found, search parent directories
|
||||
set(GIT_PREVIOUS_PARENT "${GIT_PARENT_DIR}")
|
||||
get_filename_component(GIT_PARENT_DIR ${GIT_PARENT_DIR} PATH)
|
||||
if(GIT_PARENT_DIR STREQUAL GIT_PREVIOUS_PARENT)
|
||||
# We have reached the root directory, we are not in git
|
||||
set(${_refspecvar} "GITDIR-NOTFOUND" PARENT_SCOPE)
|
||||
set(${_hashvar} "GITDIR-NOTFOUND" PARENT_SCOPE)
|
||||
return()
|
||||
endif()
|
||||
set(GIT_DIR "${GIT_PARENT_DIR}/.git")
|
||||
endwhile()
|
||||
set(GIT_DATA "${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/git-data")
|
||||
if(NOT EXISTS "${GIT_DATA}")
|
||||
file(MAKE_DIRECTORY "${GIT_DATA}")
|
||||
endif()
|
||||
|
||||
if(NOT EXISTS "${GIT_DIR}/HEAD")
|
||||
return()
|
||||
endif()
|
||||
set(HEAD_FILE "${GIT_DATA}/HEAD")
|
||||
configure_file("${GIT_DIR}/HEAD" "${HEAD_FILE}" COPYONLY)
|
||||
|
||||
configure_file("${_gitdescmoddir}/GetGitRevisionDescription.cmake.in"
|
||||
"${GIT_DATA}/grabRef.cmake"
|
||||
@ONLY)
|
||||
include("${GIT_DATA}/grabRef.cmake")
|
||||
|
||||
set(${_refspecvar} "${HEAD_REF}" PARENT_SCOPE)
|
||||
set(${_hashvar} "${HEAD_HASH}" PARENT_SCOPE)
|
||||
endfunction()
|
||||
|
||||
function(git_describe _var)
|
||||
if(NOT GIT_FOUND)
|
||||
find_package(Git QUIET)
|
||||
endif()
|
||||
get_git_head_revision(refspec hash)
|
||||
if(NOT GIT_FOUND)
|
||||
set(${_var} "GIT-NOTFOUND" PARENT_SCOPE)
|
||||
return()
|
||||
endif()
|
||||
if(NOT hash)
|
||||
set(${_var} "HEAD-HASH-NOTFOUND" PARENT_SCOPE)
|
||||
return()
|
||||
endif()
|
||||
|
||||
# TODO sanitize
|
||||
#if((${ARGN}" MATCHES "&&") OR
|
||||
# (ARGN MATCHES "||") OR
|
||||
# (ARGN MATCHES "\\;"))
|
||||
# message("Please report the following error to the project!")
|
||||
# message(FATAL_ERROR "Looks like someone's doing something nefarious with git_describe! Passed arguments ${ARGN}")
|
||||
#endif()
|
||||
|
||||
#message(STATUS "Arguments to execute_process: ${ARGN}")
|
||||
|
||||
execute_process(COMMAND
|
||||
"${GIT_EXECUTABLE}"
|
||||
describe
|
||||
${hash}
|
||||
${ARGN}
|
||||
WORKING_DIRECTORY
|
||||
"${CMAKE_SOURCE_DIR}"
|
||||
RESULT_VARIABLE
|
||||
res
|
||||
OUTPUT_VARIABLE
|
||||
out
|
||||
ERROR_QUIET
|
||||
OUTPUT_STRIP_TRAILING_WHITESPACE)
|
||||
if(NOT res EQUAL 0)
|
||||
set(out "${out}-${res}-NOTFOUND")
|
||||
endif()
|
||||
|
||||
set(${_var} "${out}" PARENT_SCOPE)
|
||||
endfunction()
|
||||
|
||||
function(git_get_exact_tag _var)
|
||||
git_describe(out --exact-match ${ARGN})
|
||||
set(${_var} "${out}" PARENT_SCOPE)
|
||||
endfunction()
|
12
cmake/UUID-Config.cmake
Normal file
12
cmake/UUID-Config.cmake
Normal file
@ -0,0 +1,12 @@
|
||||
set(oldfile ${CMAKE_SOURCE_DIR}/../Util/UUID.cpp)
|
||||
if (EXISTS ${oldfile})
|
||||
file(REMOVE_RECURSE ${oldfile})
|
||||
endif()
|
||||
|
||||
file(MD5 ${CMAKE_SOURCE_DIR}/../createHierarchy.cpp MD5PREPARE)
|
||||
file(MD5 ${CMAKE_SOURCE_DIR}/../DataStructures/StaticRTree.h MD5RTREE)
|
||||
file(MD5 ${CMAKE_SOURCE_DIR}/../DataStructures/NodeInformationHelpDesk.h MD5NODEINFO)
|
||||
file(MD5 ${CMAKE_SOURCE_DIR}/../Util/GraphLoader.h MD5GRAPH)
|
||||
file(MD5 ${CMAKE_SOURCE_DIR}/../Server/DataStructures/QueryObjectsStorage.cpp MD5OBJECTS)
|
||||
|
||||
CONFIGURE_FILE( ${CMAKE_SOURCE_DIR}/../Util/UUID.cpp.in ${CMAKE_SOURCE_DIR}/../Util/UUID.cpp )
|
9
cmake/size.cpp
Normal file
9
cmake/size.cpp
Normal file
@ -0,0 +1,9 @@
|
||||
#include <cstdlib>
|
||||
|
||||
int main( int argc, char* argv[] ) {
|
||||
size_t size = sizeof(void*);
|
||||
if ( 4 == size ) {
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
@ -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);
|
||||
@ -78,7 +78,16 @@ int main (int argc, char *argv[]) {
|
||||
ERR("Could not access <osrm-restrictions> files");
|
||||
}
|
||||
_Restriction restriction;
|
||||
UUID uuid_loaded, uuid_orig;
|
||||
unsigned usableRestrictionsCounter(0);
|
||||
restrictionsInstream.read((char*)&uuid_loaded, sizeof(UUID));
|
||||
if( !uuid_loaded.TestPrepare(uuid_orig) ) {
|
||||
WARN(
|
||||
".restrictions was prepared with different build.\n"
|
||||
"Reprocess to get rid of this warning."
|
||||
)
|
||||
}
|
||||
|
||||
restrictionsInstream.read((char*)&usableRestrictionsCounter, sizeof(unsigned));
|
||||
inputRestrictions.resize(usableRestrictionsCounter);
|
||||
restrictionsInstream.read((char *)&(inputRestrictions[0]), usableRestrictionsCounter*sizeof(_Restriction));
|
||||
@ -211,8 +220,8 @@ int main (int argc, char *argv[]) {
|
||||
unsigned numberOfNodes = 0;
|
||||
unsigned numberOfEdges = contractedEdgeList.size();
|
||||
INFO("Serializing compacted graph of " << numberOfEdges << " edges");
|
||||
std::ofstream edgeOutFile(graphOut.c_str(), std::ios::binary);
|
||||
|
||||
std::ofstream hsgr_output_stream(graphOut.c_str(), std::ios::binary);
|
||||
hsgr_output_stream.write((char*)&uuid_orig, sizeof(UUID) );
|
||||
BOOST_FOREACH(const QueryEdge & edge, contractedEdgeList) {
|
||||
if(edge.source > numberOfNodes) {
|
||||
numberOfNodes = edge.source;
|
||||
@ -237,11 +246,11 @@ int main (int argc, char *argv[]) {
|
||||
}
|
||||
++numberOfNodes;
|
||||
//Serialize numberOfNodes, nodes
|
||||
edgeOutFile.write((char*) &crc32OfNodeBasedEdgeList, sizeof(unsigned));
|
||||
edgeOutFile.write((char*) &numberOfNodes, sizeof(unsigned));
|
||||
edgeOutFile.write((char*) &_nodes[0], sizeof(StaticGraph<EdgeData>::_StrNode)*(numberOfNodes));
|
||||
hsgr_output_stream.write((char*) &crc32OfNodeBasedEdgeList, sizeof(unsigned));
|
||||
hsgr_output_stream.write((char*) &numberOfNodes, sizeof(unsigned));
|
||||
hsgr_output_stream.write((char*) &_nodes[0], sizeof(StaticGraph<EdgeData>::_StrNode)*(numberOfNodes));
|
||||
//Serialize number of Edges
|
||||
edgeOutFile.write((char*) &position, sizeof(unsigned));
|
||||
hsgr_output_stream.write((char*) &position, sizeof(unsigned));
|
||||
--numberOfNodes;
|
||||
edge = 0;
|
||||
int usedEdgeCounter = 0;
|
||||
@ -256,7 +265,7 @@ int main (int argc, char *argv[]) {
|
||||
ERR("Failed at edges of node " << node << " of " << numberOfNodes);
|
||||
}
|
||||
//Serialize edges
|
||||
edgeOutFile.write((char*) ¤tEdge, sizeof(StaticGraph<EdgeData>::_StrEdge));
|
||||
hsgr_output_stream.write((char*) ¤tEdge, sizeof(StaticGraph<EdgeData>::_StrEdge));
|
||||
++edge;
|
||||
++usedEdgeCounter;
|
||||
}
|
||||
@ -265,7 +274,7 @@ int main (int argc, char *argv[]) {
|
||||
INFO("Expansion : " << (nodeBasedNodeNumber/expansionHasFinishedTime) << " nodes/sec and "<< (edgeBasedNodeNumber/expansionHasFinishedTime) << " edges/sec");
|
||||
INFO("Contraction: " << (edgeBasedNodeNumber/expansionHasFinishedTime) << " nodes/sec and "<< usedEdgeCounter/endTime << " edges/sec");
|
||||
|
||||
edgeOutFile.close();
|
||||
hsgr_output_stream.close();
|
||||
//cleanedEdgeList.clear();
|
||||
_nodes.clear();
|
||||
INFO("finished preprocessing");
|
||||
|
@ -28,20 +28,21 @@ or see http://www.gnu.org/licenses/agpl.txt.
|
||||
#include "Util/MachineInfo.h"
|
||||
#include "Util/OpenMPWrapper.h"
|
||||
#include "Util/StringUtil.h"
|
||||
#include "Util/UUID.h"
|
||||
#include "typedefs.h"
|
||||
|
||||
#include <cstdlib>
|
||||
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
|
||||
#include <string>
|
||||
|
||||
typedef BaseConfiguration ExtractorConfiguration;
|
||||
|
||||
ExtractorCallbacks * extractCallBacks;
|
||||
UUID uuid;
|
||||
|
||||
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>]");
|
||||
@ -50,36 +51,43 @@ int main (int argc, char *argv[]) {
|
||||
/*** Setup Scripting Environment ***/
|
||||
ScriptingEnvironment scriptingEnvironment((argc > 2 ? argv[2] : "profile.lua"));
|
||||
|
||||
unsigned numberOfThreads = omp_get_num_procs();
|
||||
unsigned number_of_threads = omp_get_num_procs();
|
||||
if(testDataFile("extractor.ini")) {
|
||||
ExtractorConfiguration extractorConfig("extractor.ini");
|
||||
BaseConfiguration extractorConfig("extractor.ini");
|
||||
unsigned rawNumber = stringToInt(extractorConfig.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("extracting data from input file " << argv[1]);
|
||||
bool isPBF(false);
|
||||
std::string outputFileName(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 = outputFileName.find(".osm.bz2");
|
||||
std::string::size_type pos = output_file_name.find(".osm.bz2");
|
||||
if(pos==std::string::npos) {
|
||||
pos = outputFileName.find(".osm.pbf");
|
||||
pos = output_file_name.find(".osm.pbf");
|
||||
if(pos!=std::string::npos) {
|
||||
isPBF = true;
|
||||
file_has_pbf_format = true;
|
||||
}
|
||||
}
|
||||
if(pos==std::string::npos) {
|
||||
pos = output_file_name.find(".pbf");
|
||||
if(pos!=std::string::npos) {
|
||||
file_has_pbf_format = true;
|
||||
}
|
||||
}
|
||||
if(pos!=std::string::npos) {
|
||||
outputFileName.replace(pos, 8, ".osrm");
|
||||
output_file_name.replace(pos, 8, ".osrm");
|
||||
restrictionsFileName.replace(pos, 8, ".osrm.restrictions");
|
||||
} else {
|
||||
pos=outputFileName.find(".osm");
|
||||
pos=output_file_name.find(".osm");
|
||||
if(pos!=std::string::npos) {
|
||||
outputFileName.replace(pos, 5, ".osrm");
|
||||
output_file_name.replace(pos, 5, ".osrm");
|
||||
restrictionsFileName.replace(pos, 5, ".osrm.restrictions");
|
||||
} else {
|
||||
outputFileName.append(".osrm");
|
||||
output_file_name.append(".osrm");
|
||||
restrictionsFileName.append(".osrm.restrictions");
|
||||
}
|
||||
}
|
||||
@ -96,7 +104,7 @@ int main (int argc, char *argv[]) {
|
||||
stringMap[""] = 0;
|
||||
extractCallBacks = new ExtractorCallbacks(&externalMemory, &stringMap);
|
||||
BaseParser* parser;
|
||||
if(isPBF) {
|
||||
if(file_has_pbf_format) {
|
||||
parser = new PBFParser(argv[1], extractCallBacks, scriptingEnvironment);
|
||||
} else {
|
||||
parser = new XMLParser(argv[1], extractCallBacks, scriptingEnvironment);
|
||||
@ -106,18 +114,25 @@ int main (int argc, char *argv[]) {
|
||||
ERR("Parser not initialized!");
|
||||
}
|
||||
INFO("Parsing in progress..");
|
||||
double time = get_timestamp();
|
||||
double parsing_start_time = get_timestamp();
|
||||
parser->Parse();
|
||||
INFO("Parsing finished after " << get_timestamp() - time << " seconds");
|
||||
INFO("Parsing finished after " <<
|
||||
(get_timestamp() - parsing_start_time) <<
|
||||
" seconds"
|
||||
);
|
||||
|
||||
externalMemory.PrepareData(outputFileName, restrictionsFileName, amountOfRAM);
|
||||
externalMemory.PrepareData(output_file_name, restrictionsFileName, amountOfRAM);
|
||||
|
||||
stringMap.clear();
|
||||
delete parser;
|
||||
delete extractCallBacks;
|
||||
INFO("finished after " << get_timestamp() - earliestTime << "s");
|
||||
|
||||
INFO("extraction finished after " << get_timestamp() - startup_time << "s");
|
||||
|
||||
std::cout << "\nRun:\n"
|
||||
"./osrm-prepare " << outputFileName << " " << restrictionsFileName << std::endl;
|
||||
<< "./osrm-prepare " << output_file_name << " " << restrictionsFileName
|
||||
<< std::endl;
|
||||
return 0;
|
||||
} catch(std::exception & e) {
|
||||
WARN("unhandled exception: " << e.what());
|
||||
}
|
||||
}
|
||||
|
@ -14,7 +14,7 @@ Feature: Car - Barriers
|
||||
| border_control | x |
|
||||
| toll_booth | x |
|
||||
| sally_port | x |
|
||||
| entrance | |
|
||||
| entrance | x |
|
||||
| wall | |
|
||||
| fence | |
|
||||
| some_tag | |
|
||||
|
@ -15,7 +15,7 @@ Handle oneways streets, as defined at http://wiki.openstreetmap.org/wiki/OSM_tag
|
||||
| highway | oneway | forw | backw |
|
||||
| primary | -1 | | x |
|
||||
|
||||
Scenario: Car - Implied onewatys
|
||||
Scenario: Car - Implied oneways
|
||||
Then routability should be
|
||||
| highway | junction | forw | backw |
|
||||
| motorway | | x | |
|
||||
@ -25,6 +25,12 @@ Handle oneways streets, as defined at http://wiki.openstreetmap.org/wiki/OSM_tag
|
||||
| motorway_link | roundabout | x | |
|
||||
| primary | roundabout | x | |
|
||||
|
||||
Scenario: Car - Overrule implied oneway
|
||||
Then routability should be
|
||||
| highway | oneway | forw | backw |
|
||||
| motorway | no | x | x |
|
||||
| motorway_link | no | x | x |
|
||||
|
||||
Scenario: Car - Around the Block
|
||||
Given the node map
|
||||
| a | b |
|
||||
|
@ -190,6 +190,11 @@ function way_function (way)
|
||||
-- this encoding scheme is excepted to be a temporary solution
|
||||
end
|
||||
|
||||
-- roundabout handling
|
||||
if "roundabout" == junction then
|
||||
way.roundabout = true;
|
||||
end
|
||||
|
||||
-- speed
|
||||
if route_speeds[route] then
|
||||
-- ferries (doesn't cover routes tagged using relations)
|
||||
|
@ -1,7 +1,7 @@
|
||||
-- Begin of globals
|
||||
require("lib/access")
|
||||
|
||||
barrier_whitelist = { ["cattle_grid"] = true, ["border_control"] = true, ["toll_booth"] = true, ["sally_port"] = true, ["gate"] = true, ["no"] = true}
|
||||
barrier_whitelist = { ["cattle_grid"] = true, ["border_control"] = true, ["toll_booth"] = true, ["sally_port"] = true, ["gate"] = true, ["no"] = true, ["entrance"] = true}
|
||||
access_tag_whitelist = { ["yes"] = true, ["motorcar"] = true, ["motor_vehicle"] = true, ["vehicle"] = true, ["permissive"] = true, ["designated"] = true }
|
||||
access_tag_blacklist = { ["no"] = true, ["private"] = true, ["agricultural"] = true, ["forestry"] = true }
|
||||
access_tag_restricted = { ["destination"] = true, ["delivery"] = true }
|
||||
@ -185,7 +185,13 @@ function way_function (way)
|
||||
if obey_oneway then
|
||||
if oneway == "-1" then
|
||||
way.direction = Way.opposite
|
||||
elseif oneway == "yes" or oneway == "1" or oneway == "true" or junction == "roundabout" or highway == "motorway_link" or highway == "motorway" then
|
||||
elseif oneway == "yes" or
|
||||
oneway == "1" or
|
||||
oneway == "true" or
|
||||
junction == "roundabout" or
|
||||
(highway == "motorway_link" and oneway ~="no") or
|
||||
(highway == "motorway" and oneway ~= "no")
|
||||
then
|
||||
way.direction = Way.oneway
|
||||
end
|
||||
end
|
||||
|
66
routed.cpp
66
routed.cpp
@ -17,34 +17,29 @@ 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"
|
||||
#include "Util/UUID.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 +65,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 +78,10 @@ int main (int argc, char * argv[]) {
|
||||
//}
|
||||
|
||||
try {
|
||||
std::cout << std::endl << "[server] starting up engines, saved at " << __TIMESTAMP__ << std::endl;
|
||||
//std::cout << "fingerprint: " << UUID::GetInstance().GetUUID() << std::endl;
|
||||
|
||||
std::cout << "starting up engines, compiled at " <<
|
||||
__DATE__ << ", " __TIME__ << std::endl;
|
||||
|
||||
#ifndef _WIN32
|
||||
int sig = 0;
|
||||
@ -93,28 +91,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 +127,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;
|
||||
|
14
server.ini
14
server.ini
@ -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
|
||||
|
@ -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>
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user