Merge branch 'develop'

This commit is contained in:
Dennis Luxen 2015-01-06 11:03:29 +01:00
commit 725b93a961
333 changed files with 28923 additions and 5399 deletions

5
.gitignore vendored
View File

@ -36,8 +36,8 @@ Thumbs.db
# build related files #
#######################
/build/
/Util/FingerPrint.cpp
/Util/GitDescription.cpp
/Util/finger_print.cpp
/Util/git_sha.cpp
/cmake/postinst
# Eclipse related files #
@ -81,6 +81,7 @@ stxxl.errlog
/osrm-unlock-all
/osrm-cli
/osrm-check-hsgr
/osrm-springclean
/nohup.out
# Sandbox folder #

View File

@ -7,15 +7,17 @@ install:
- sudo apt-add-repository -y ppa:ubuntu-toolchain-r/test
- sudo add-apt-repository -y ppa:boost-latest/ppa
- sudo apt-get update >/dev/null
- sudo apt-get -q install protobuf-compiler libprotoc-dev libprotobuf7 libprotobuf-dev libosmpbf-dev libbz2-dev libstxxl-dev libstxxl1 libxml2-dev libzip-dev lua5.1 liblua5.1-0-dev rubygems libtbb-dev
- sudo apt-get -q install protobuf-compiler libprotoc-dev libprotobuf7 libprotobuf-dev libbz2-dev libstxxl-dev libstxxl1 libxml2-dev libzip-dev lua5.1 liblua5.1-0-dev rubygems libtbb-dev
- sudo apt-get -q install g++-4.8
- sudo apt-get install libboost1.54-all-dev
#luabind
# luabind
- curl https://gist.githubusercontent.com/DennisOSRM/f2eb7b948e6fe1ae319e/raw/install-luabind.sh | sudo bash
#osmosis
# osmosis
- curl -s https://gist.githubusercontent.com/DennisOSRM/803a64a9178ec375069f/raw/ | sudo bash
#cmake
# cmake
- curl -s https://gist.githubusercontent.com/DennisOSRM/5fad9bee5c7f09fd7fc9/raw/ | sudo bash
# osmpbf library
- curl -s https://gist.githubusercontent.com/DennisOSRM/13b1b4fe38a57ead850e/raw/install_osmpbf.sh | sudo bash
before_script:
- rvm use 1.9.3
- gem install bundler
@ -26,6 +28,7 @@ before_script:
script:
- make -j 2
- make -j 2 tests
- ./datastructure-tests
- cd ..
- cucumber -p verify
after_script:

View File

@ -1,459 +0,0 @@
/*
Copyright (c) 2013, Project OSRM, Dennis Luxen, others
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
Redistributions of source code must retain the above copyright notice, this list
of conditions and the following disclaimer.
Redistributions in binary form must reproduce the above copyright notice, this
list of conditions and the following disclaimer in the documentation and/or
other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef STRONGLYCONNECTEDCOMPONENTS_H_
#define STRONGLYCONNECTEDCOMPONENTS_H_
#include "../typedefs.h"
#include "../DataStructures/DeallocatingVector.h"
#include "../DataStructures/DynamicGraph.h"
#include "../DataStructures/ImportEdge.h"
#include "../DataStructures/QueryNode.h"
#include "../DataStructures/Percent.h"
#include "../DataStructures/Range.h"
#include "../DataStructures/Restriction.h"
#include "../DataStructures/TurnInstructions.h"
#include "../Util/OSRMException.h"
#include "../Util/simple_logger.hpp"
#include "../Util/StdHashExtensions.h"
#include "../Util/TimingUtil.h"
#include <osrm/Coordinate.h>
#include <boost/assert.hpp>
#include <boost/filesystem.hpp>
#include <tbb/parallel_sort.h>
#ifdef __APPLE__
#include <gdal.h>
#include <ogrsf_frmts.h>
#else
#include <gdal/gdal.h>
#include <gdal/ogrsf_frmts.h>
#endif
#include <cstdint>
#include <memory>
#include <stack>
#include <unordered_map>
#include <unordered_set>
#include <vector>
class TarjanSCC
{
private:
struct TarjanNode
{
TarjanNode() : index(SPECIAL_NODEID), low_link(SPECIAL_NODEID), on_stack(false) {}
unsigned index;
unsigned low_link;
bool on_stack;
};
struct TarjanEdgeData
{
TarjanEdgeData() : distance(INVALID_EDGE_WEIGHT), name_id(INVALID_NAMEID) {}
TarjanEdgeData(int distance, unsigned name_id) : distance(distance), name_id(name_id) {}
int distance;
unsigned name_id;
};
struct TarjanStackFrame
{
explicit TarjanStackFrame(NodeID v, NodeID parent) : v(v), parent(parent) {}
NodeID v;
NodeID parent;
};
using TarjanDynamicGraph = DynamicGraph<TarjanEdgeData>;
using TarjanEdge = TarjanDynamicGraph::InputEdge;
using RestrictionSource = std::pair<NodeID, NodeID>;
using RestrictionTarget = std::pair<NodeID, bool>;
using EmanatingRestrictionsVector = std::vector<RestrictionTarget>;
using RestrictionMap = std::unordered_map<RestrictionSource, unsigned>;
std::vector<NodeInfo> m_coordinate_list;
std::vector<EmanatingRestrictionsVector> m_restriction_bucket_list;
std::shared_ptr<TarjanDynamicGraph> m_node_based_graph;
std::unordered_set<NodeID> barrier_node_list;
std::unordered_set<NodeID> traffic_light_list;
unsigned m_restriction_counter;
RestrictionMap m_restriction_map;
public:
TarjanSCC(int number_of_nodes,
std::vector<NodeBasedEdge> &input_edges,
std::vector<NodeID> &bn,
std::vector<NodeID> &tl,
std::vector<TurnRestriction> &irs,
std::vector<NodeInfo> &nI)
: m_coordinate_list(nI), m_restriction_counter(irs.size())
{
TIMER_START(SCC_LOAD);
for (const TurnRestriction &restriction : irs)
{
std::pair<NodeID, NodeID> restriction_source = {restriction.fromNode,
restriction.viaNode};
unsigned index = 0;
const auto restriction_iterator = m_restriction_map.find(restriction_source);
if (restriction_iterator == m_restriction_map.end())
{
index = m_restriction_bucket_list.size();
m_restriction_bucket_list.resize(index + 1);
m_restriction_map.emplace(restriction_source, index);
}
else
{
index = restriction_iterator->second;
// Map already contains an is_only_*-restriction
if (m_restriction_bucket_list.at(index).begin()->second)
{
continue;
}
else if (restriction.flags.isOnly)
{
// We are going to insert an is_only_*-restriction. There can be only one.
m_restriction_bucket_list.at(index).clear();
}
}
m_restriction_bucket_list.at(index)
.emplace_back(restriction.toNode, restriction.flags.isOnly);
}
barrier_node_list.insert(bn.begin(), bn.end());
traffic_light_list.insert(tl.begin(), tl.end());
DeallocatingVector<TarjanEdge> edge_list;
for (const NodeBasedEdge &input_edge : input_edges)
{
if (input_edge.source == input_edge.target)
{
continue;
}
if (input_edge.forward)
{
edge_list.emplace_back(input_edge.source,
input_edge.target,
(std::max)((int)input_edge.weight, 1),
input_edge.name_id);
}
if (input_edge.backward)
{
edge_list.emplace_back(input_edge.target,
input_edge.source,
(std::max)((int)input_edge.weight, 1),
input_edge.name_id);
}
}
input_edges.clear();
input_edges.shrink_to_fit();
BOOST_ASSERT_MSG(0 == input_edges.size() && 0 == input_edges.capacity(),
"input edge vector not properly deallocated");
tbb::parallel_sort(edge_list.begin(), edge_list.end());
m_node_based_graph = std::make_shared<TarjanDynamicGraph>(number_of_nodes, edge_list);
TIMER_STOP(SCC_LOAD);
SimpleLogger().Write() << "Loading data into SCC took " << TIMER_MSEC(SCC_LOAD)/1000. << "s";
}
~TarjanSCC() { m_node_based_graph.reset(); }
void Run()
{
TIMER_START(SCC_RUN_SETUP);
// remove files from previous run if exist
DeleteFileIfExists("component.dbf");
DeleteFileIfExists("component.shx");
DeleteFileIfExists("component.shp");
Percent p(m_node_based_graph->GetNumberOfNodes());
OGRRegisterAll();
const char *pszDriverName = "ESRI Shapefile";
OGRSFDriver *poDriver =
OGRSFDriverRegistrar::GetRegistrar()->GetDriverByName(pszDriverName);
if (nullptr == poDriver)
{
throw OSRMException("ESRI Shapefile driver not available");
}
OGRDataSource *poDS = poDriver->CreateDataSource("component.shp", nullptr);
if (nullptr == poDS)
{
throw OSRMException("Creation of output file failed");
}
OGRSpatialReference *poSRS = new OGRSpatialReference();
poSRS->importFromEPSG(4326);
OGRLayer *poLayer = poDS->CreateLayer("component", poSRS, wkbLineString, nullptr);
if (nullptr == poLayer)
{
throw OSRMException("Layer creation failed.");
}
TIMER_STOP(SCC_RUN_SETUP);
SimpleLogger().Write() << "shapefile setup took " << TIMER_MSEC(SCC_RUN_SETUP)/1000. << "s";
TIMER_START(SCC_RUN);
// The following is a hack to distinguish between stuff that happens
// before the recursive call and stuff that happens after
std::stack<TarjanStackFrame> recursion_stack;
// true = stuff before, false = stuff after call
std::stack<NodeID> tarjan_stack;
std::vector<unsigned> components_index(m_node_based_graph->GetNumberOfNodes(),
SPECIAL_NODEID);
std::vector<NodeID> component_size_vector;
std::vector<TarjanNode> tarjan_node_list(m_node_based_graph->GetNumberOfNodes());
unsigned component_index = 0, size_of_current_component = 0;
int index = 0;
const NodeID last_node = m_node_based_graph->GetNumberOfNodes();
std::vector<bool> processing_node_before_recursion(m_node_based_graph->GetNumberOfNodes(), true);
for(const NodeID node : osrm::irange(0u, last_node))
{
if (SPECIAL_NODEID == components_index[node])
{
recursion_stack.emplace(TarjanStackFrame(node, node));
}
while (!recursion_stack.empty())
{
TarjanStackFrame currentFrame = recursion_stack.top();
const NodeID v = currentFrame.v;
recursion_stack.pop();
const bool before_recursion = processing_node_before_recursion[v];
if (before_recursion && tarjan_node_list[v].index != UINT_MAX)
{
continue;
}
if (before_recursion)
{
// Mark frame to handle tail of recursion
recursion_stack.emplace(currentFrame);
processing_node_before_recursion[v] = false;
// Mark essential information for SCC
tarjan_node_list[v].index = index;
tarjan_node_list[v].low_link = index;
tarjan_stack.push(v);
tarjan_node_list[v].on_stack = true;
++index;
// Traverse outgoing edges
for (const auto current_edge : m_node_based_graph->GetAdjacentEdgeRange(v))
{
const TarjanDynamicGraph::NodeIterator vprime =
m_node_based_graph->GetTarget(current_edge);
if (SPECIAL_NODEID == tarjan_node_list[vprime].index)
{
recursion_stack.emplace(TarjanStackFrame(vprime, v));
}
else
{
if (tarjan_node_list[vprime].on_stack &&
tarjan_node_list[vprime].index < tarjan_node_list[v].low_link)
{
tarjan_node_list[v].low_link = tarjan_node_list[vprime].index;
}
}
}
}
else
{
processing_node_before_recursion[v] = true;
tarjan_node_list[currentFrame.parent].low_link =
std::min(tarjan_node_list[currentFrame.parent].low_link,
tarjan_node_list[v].low_link);
// after recursion, lets do cycle checking
// Check if we found a cycle. This is the bottom part of the recursion
if (tarjan_node_list[v].low_link == tarjan_node_list[v].index)
{
NodeID vprime;
do
{
vprime = tarjan_stack.top();
tarjan_stack.pop();
tarjan_node_list[vprime].on_stack = false;
components_index[vprime] = component_index;
++size_of_current_component;
} while (v != vprime);
component_size_vector.emplace_back(size_of_current_component);
if (size_of_current_component > 1000)
{
SimpleLogger().Write() << "large component [" << component_index
<< "]=" << size_of_current_component;
}
++component_index;
size_of_current_component = 0;
}
}
}
}
TIMER_STOP(SCC_RUN);
SimpleLogger().Write() << "SCC run took: " << TIMER_MSEC(SCC_RUN)/1000. << "s";
SimpleLogger().Write() << "identified: " << component_size_vector.size()
<< " many components, marking small components";
TIMER_START(SCC_OUTPUT);
const unsigned size_one_counter = std::count_if(component_size_vector.begin(),
component_size_vector.end(),
[](unsigned value)
{
return 1 == value;
});
SimpleLogger().Write() << "identified " << size_one_counter << " SCCs of size 1";
uint64_t total_network_distance = 0;
p.reinit(m_node_based_graph->GetNumberOfNodes());
// const NodeID last_u_node = m_node_based_graph->GetNumberOfNodes();
for (const NodeID source : osrm::irange(0u, last_node))
{
p.printIncrement();
for (const auto current_edge : m_node_based_graph->GetAdjacentEdgeRange(source))
{
const TarjanDynamicGraph::NodeIterator target =
m_node_based_graph->GetTarget(current_edge);
if (source < target ||
m_node_based_graph->EndEdges(target) ==
m_node_based_graph->FindEdge(target, source))
{
total_network_distance +=
100 * FixedPointCoordinate::ApproximateEuclideanDistance(
m_coordinate_list[source].lat,
m_coordinate_list[source].lon,
m_coordinate_list[target].lat,
m_coordinate_list[target].lon);
BOOST_ASSERT(current_edge != SPECIAL_EDGEID);
BOOST_ASSERT(source != SPECIAL_NODEID);
BOOST_ASSERT(target != SPECIAL_NODEID);
const unsigned size_of_containing_component =
std::min(component_size_vector[components_index[source]],
component_size_vector[components_index[target]]);
// edges that end on bollard nodes may actually be in two distinct components
if (size_of_containing_component < 10)
{
OGRLineString lineString;
lineString.addPoint(m_coordinate_list[source].lon / COORDINATE_PRECISION,
m_coordinate_list[source].lat / COORDINATE_PRECISION);
lineString.addPoint(m_coordinate_list[target].lon / COORDINATE_PRECISION,
m_coordinate_list[target].lat / COORDINATE_PRECISION);
OGRFeature *poFeature = OGRFeature::CreateFeature(poLayer->GetLayerDefn());
poFeature->SetGeometry(&lineString);
if (OGRERR_NONE != poLayer->CreateFeature(poFeature))
{
throw OSRMException("Failed to create feature in shapefile.");
}
OGRFeature::DestroyFeature(poFeature);
}
}
}
}
OGRDataSource::DestroyDataSource(poDS);
component_size_vector.clear();
component_size_vector.shrink_to_fit();
BOOST_ASSERT_MSG(0 == component_size_vector.size() && 0 == component_size_vector.capacity(),
"component_size_vector not properly deallocated");
components_index.clear();
components_index.shrink_to_fit();
BOOST_ASSERT_MSG(0 == components_index.size() && 0 == components_index.capacity(),
"components_index not properly deallocated");
TIMER_STOP(SCC_OUTPUT);
SimpleLogger().Write() << "generating output took: " << TIMER_MSEC(SCC_OUTPUT)/1000. << "s";
SimpleLogger().Write() << "total network distance: "
<< (uint64_t)total_network_distance / 100 / 1000. << " km";
}
private:
unsigned CheckForEmanatingIsOnlyTurn(const NodeID u, const NodeID v) const
{
std::pair<NodeID, NodeID> restriction_source = {u, v};
const auto restriction_iterator = m_restriction_map.find(restriction_source);
if (restriction_iterator != m_restriction_map.end())
{
const unsigned index = restriction_iterator->second;
for (const RestrictionSource &restriction_target : m_restriction_bucket_list.at(index))
{
if (restriction_target.second)
{
return restriction_target.first;
}
}
}
return SPECIAL_NODEID;
}
bool CheckIfTurnIsRestricted(const NodeID u, const NodeID v, const NodeID w) const
{
// only add an edge if turn is not a U-turn except it is the end of dead-end street.
std::pair<NodeID, NodeID> restriction_source = {u, v};
const auto restriction_iterator = m_restriction_map.find(restriction_source);
if (restriction_iterator != m_restriction_map.end())
{
const unsigned index = restriction_iterator->second;
for (const RestrictionTarget &restriction_target : m_restriction_bucket_list.at(index))
{
if (w == restriction_target.first)
{
return true;
}
}
}
return false;
}
void DeleteFileIfExists(const std::string &file_name) const
{
if (boost::filesystem::exists(file_name))
{
boost::filesystem::remove(file_name);
}
}
};
#endif /* STRONGLYCONNECTEDCOMPONENTS_H_ */

View File

@ -1,130 +0,0 @@
#include "../DataStructures/OriginalEdgeData.h"
#include "../DataStructures/QueryNode.h"
#include "../DataStructures/SharedMemoryVectorWrapper.h"
#include "../DataStructures/StaticRTree.h"
#include "../Util/BoostFileSystemFix.h"
#include "../DataStructures/EdgeBasedNode.h"
#include <osrm/Coordinate.h>
#include <random>
// Choosen by a fair W20 dice roll (this value is completely arbitrary)
constexpr unsigned RANDOM_SEED = 13;
constexpr int32_t WORLD_MIN_LAT = -90 * COORDINATE_PRECISION;
constexpr int32_t WORLD_MAX_LAT = 90 * COORDINATE_PRECISION;
constexpr int32_t WORLD_MIN_LON = -180 * COORDINATE_PRECISION;
constexpr int32_t WORLD_MAX_LON = 180 * COORDINATE_PRECISION;
using RTreeLeaf = EdgeBasedNode;
using FixedPointCoordinateListPtr = std::shared_ptr<std::vector<FixedPointCoordinate>>;
using BenchStaticRTree = StaticRTree<RTreeLeaf, ShM<FixedPointCoordinate, false>::vector, false>;
FixedPointCoordinateListPtr LoadCoordinates(const boost::filesystem::path &nodes_file)
{
boost::filesystem::ifstream nodes_input_stream(nodes_file, std::ios::binary);
NodeInfo current_node;
unsigned number_of_coordinates = 0;
nodes_input_stream.read((char *)&number_of_coordinates, sizeof(unsigned));
auto coords = std::make_shared<std::vector<FixedPointCoordinate>>(number_of_coordinates);
for (unsigned i = 0; i < number_of_coordinates; ++i)
{
nodes_input_stream.read((char *)&current_node, sizeof(NodeInfo));
coords->at(i) = FixedPointCoordinate(current_node.lat, current_node.lon);
BOOST_ASSERT((std::abs(coords->at(i).lat) >> 30) == 0);
BOOST_ASSERT((std::abs(coords->at(i).lon) >> 30) == 0);
}
nodes_input_stream.close();
return coords;
}
void Benchmark(BenchStaticRTree &rtree, unsigned num_queries)
{
std::mt19937 mt_rand(RANDOM_SEED);
std::uniform_int_distribution<> lat_udist(WORLD_MIN_LAT, WORLD_MAX_LAT);
std::uniform_int_distribution<> lon_udist(WORLD_MIN_LON, WORLD_MAX_LON);
std::vector<FixedPointCoordinate> queries;
for (unsigned i = 0; i < num_queries; i++)
{
queries.emplace_back(FixedPointCoordinate(lat_udist(mt_rand), lon_udist(mt_rand)));
}
const unsigned num_results = 5;
std::cout << "#### IncrementalFindPhantomNodeForCoordinate : " << num_results
<< " phantom nodes"
<< "\n";
TIMER_START(query_phantom);
std::vector<PhantomNode> resulting_phantom_node_vector;
for (const auto &q : queries)
{
resulting_phantom_node_vector.clear();
rtree.IncrementalFindPhantomNodeForCoordinate(
q, resulting_phantom_node_vector, 3, num_results);
resulting_phantom_node_vector.clear();
rtree.IncrementalFindPhantomNodeForCoordinate(
q, resulting_phantom_node_vector, 17, num_results);
}
TIMER_STOP(query_phantom);
std::cout << "Took " << TIMER_MSEC(query_phantom) << " msec for " << num_queries << " queries."
<< "\n";
std::cout << TIMER_MSEC(query_phantom) / ((double)num_queries) << " msec/query."
<< "\n";
std::cout << "#### LocateClosestEndPointForCoordinate"
<< "\n";
TIMER_START(query_endpoint);
FixedPointCoordinate result;
for (const auto &q : queries)
{
rtree.LocateClosestEndPointForCoordinate(q, result, 3);
}
TIMER_STOP(query_endpoint);
std::cout << "Took " << TIMER_MSEC(query_endpoint) << " msec for " << num_queries << " queries."
<< "\n";
std::cout << TIMER_MSEC(query_endpoint) / ((double)num_queries) << " msec/query."
<< "\n";
std::cout << "#### FindPhantomNodeForCoordinate"
<< "\n";
TIMER_START(query_phantomnode);
for (const auto &q : queries)
{
PhantomNode phantom;
rtree.FindPhantomNodeForCoordinate(q, phantom, 3);
}
TIMER_STOP(query_phantomnode);
std::cout << "Took " << TIMER_MSEC(query_phantomnode) << " msec for " << num_queries
<< " queries."
<< "\n";
std::cout << TIMER_MSEC(query_phantomnode) / ((double)num_queries) << " msec/query."
<< "\n";
}
int main(int argc, char **argv)
{
if (argc < 4)
{
std::cout << "./rtree-bench file.ramIndex file.fileIndx file.nodes"
<< "\n";
return 1;
}
const char *ramPath = argv[1];
const char *filePath = argv[2];
const char *nodesPath = argv[3];
auto coords = LoadCoordinates(nodesPath);
BenchStaticRTree rtree(ramPath, filePath, coords);
Benchmark(rtree, 10000);
return 0;
}

View File

@ -1,6 +1,6 @@
cmake_minimum_required(VERSION 2.8.8)
if( CMAKE_SOURCE_DIR STREQUAL CMAKE_BINARY_DIR AND NOT MSVC_IDE )
if(CMAKE_SOURCE_DIR STREQUAL CMAKE_BINARY_DIR AND NOT MSVC_IDE)
message(FATAL_ERROR "In-source builds are not allowed.
Please create a directory and run cmake from there, passing the path to this source directory as the last argument.
This process created the file `CMakeCache.txt' and the directory `CMakeFiles'. Please delete them.")
@ -31,46 +31,52 @@ OPTION(WITH_TOOLS "Build OSRM tools" OFF)
OPTION(BUILD_TOOLS "Build OSRM tools" OFF)
include_directories(${CMAKE_SOURCE_DIR}/Include/)
include_directories(${CMAKE_SOURCE_DIR}/third_party/)
add_custom_command(OUTPUT ${CMAKE_SOURCE_DIR}/Util/FingerPrint.cpp FingerPrint.cpp.alwaysbuild
add_custom_command(OUTPUT ${CMAKE_SOURCE_DIR}/Util/finger_print.cpp finger_print.cpp.alwaysbuild
COMMAND ${CMAKE_COMMAND} -DSOURCE_DIR=${CMAKE_SOURCE_DIR}
-P ${CMAKE_CURRENT_SOURCE_DIR}/cmake/FingerPrint-Config.cmake
DEPENDS
${CMAKE_SOURCE_DIR}/Util/FingerPrint.cpp.in
COMMENT "Configuring FingerPrint.cpp"
${CMAKE_SOURCE_DIR}/Util/finger_print.cpp.in
COMMENT "Configuring finger_print.cpp"
VERBATIM)
add_custom_target(FingerPrintConfigure DEPENDS ${CMAKE_SOURCE_DIR}/Util/FingerPrint.cpp)
add_custom_target(tests DEPENDS datastructure-tests)
add_custom_target(FingerPrintConfigure DEPENDS ${CMAKE_SOURCE_DIR}/Util/finger_print.cpp)
add_custom_target(tests DEPENDS datastructure-tests algorithm-tests)
add_custom_target(benchmarks DEPENDS rtree-bench)
set(BOOST_COMPONENTS date_time filesystem iostreams program_options regex system thread unit_test_framework)
configure_file(
${CMAKE_SOURCE_DIR}/Util/GitDescription.cpp.in
${CMAKE_SOURCE_DIR}/Util/GitDescription.cpp
${CMAKE_SOURCE_DIR}/Util/git_sha.cpp.in
${CMAKE_SOURCE_DIR}/Util/git_sha.cpp
)
file(GLOB ExtractorGlob Extractor/*.cpp)
file(GLOB ImporterGlob DataStructures/Import*.cpp)
file(GLOB ExtractorGlob extractor/*.cpp)
file(GLOB ImporterGlob data_structures/import_edge.cpp data_structures/external_memory_node.cpp)
add_library(IMPORT OBJECT ${ImporterGlob})
add_library(LOGGER OBJECT Util/simple_logger.cpp)
add_library(PHANTOMNODE OBJECT data_structures/phantom_node.cpp)
add_library(EXCEPTION OBJECT Util/osrm_exception.cpp)
set(ExtractorSources extractor.cpp ${ExtractorGlob})
add_executable(osrm-extract ${ExtractorSources} $<TARGET_OBJECTS:COORDINATE> $<TARGET_OBJECTS:FINGERPRINT> $<TARGET_OBJECTS:GITDESCRIPTION> $<TARGET_OBJECTS:IMPORT> $<TARGET_OBJECTS:LOGGER>)
set(ExtractorSources extract.cpp ${ExtractorGlob})
add_executable(osrm-extract ${ExtractorSources} $<TARGET_OBJECTS:COORDINATE> $<TARGET_OBJECTS:FINGERPRINT> $<TARGET_OBJECTS:GITDESCRIPTION> $<TARGET_OBJECTS:IMPORT> $<TARGET_OBJECTS:LOGGER> $<TARGET_OBJECTS:EXCEPTION>)
file(GLOB PrepareGlob Contractor/*.cpp DataStructures/HilbertValue.cpp DataStructures/RestrictionMap.cpp Util/compute_angle.cpp)
add_library(RESTRICTION OBJECT data_structures/restriction_map.cpp)
file(GLOB PrepareGlob contractor/*.cpp data_structures/hilbert_value.cpp Util/compute_angle.cpp {RestrictionMapGlob})
set(PrepareSources prepare.cpp ${PrepareGlob})
add_executable(osrm-prepare ${PrepareSources} $<TARGET_OBJECTS:FINGERPRINT> $<TARGET_OBJECTS:GITDESCRIPTION> $<TARGET_OBJECTS:COORDINATE> $<TARGET_OBJECTS:IMPORT> $<TARGET_OBJECTS:LOGGER>)
add_executable(osrm-prepare ${PrepareSources} $<TARGET_OBJECTS:FINGERPRINT> $<TARGET_OBJECTS:GITDESCRIPTION> $<TARGET_OBJECTS:COORDINATE> $<TARGET_OBJECTS:IMPORT> $<TARGET_OBJECTS:LOGGER> $<TARGET_OBJECTS:RESTRICTION> $<TARGET_OBJECTS:EXCEPTION>)
file(GLOB ServerGlob Server/*.cpp)
file(GLOB DescriptorGlob Descriptors/*.cpp)
file(GLOB DatastructureGlob DataStructures/SearchEngineData.cpp DataStructures/RouteParameters.cpp)
list(REMOVE_ITEM DatastructureGlob DataStructures/Coordinate.cpp)
file(GLOB CoordinateGlob DataStructures/Coordinate.cpp)
file(GLOB AlgorithmGlob Algorithms/*.cpp)
file(GLOB DescriptorGlob descriptors/*.cpp)
file(GLOB DatastructureGlob data_structures/search_engine_data.cpp data_structures/route_parameters.cpp Util/bearing.cpp)
list(REMOVE_ITEM DatastructureGlob data_structures/Coordinate.cpp)
file(GLOB CoordinateGlob data_structures/Coordinate.cpp)
file(GLOB AlgorithmGlob algorithms/*.cpp)
file(GLOB HttpGlob Server/Http/*.cpp)
file(GLOB LibOSRMGlob Library/*.cpp)
file(GLOB DataStructureTestsGlob UnitTests/DataStructures/*.cpp DataStructures/HilbertValue.cpp)
file(GLOB DataStructureTestsGlob UnitTests/data_structures/*.cpp data_structures/hilbert_value.cpp)
file(GLOB AlgorithmTestsGlob UnitTests/Algorithms/*.cpp)
set(
OSRMSources
@ -82,19 +88,20 @@ set(
${HttpGlob}
)
add_library(COORDINATE OBJECT ${CoordinateGlob})
add_library(FINGERPRINT OBJECT Util/FingerPrint.cpp)
add_library(GITDESCRIPTION OBJECT Util/GitDescription.cpp)
add_library(OSRM ${OSRMSources} $<TARGET_OBJECTS:GITDESCRIPTION> $<TARGET_OBJECTS:FINGERPRINT> $<TARGET_OBJECTS:COORDINATE> $<TARGET_OBJECTS:LOGGER>)
add_library(FINGERPRINT OBJECT Util/finger_print.cpp)
add_library(GITDESCRIPTION OBJECT Util/git_sha.cpp)
add_library(OSRM ${OSRMSources} $<TARGET_OBJECTS:GITDESCRIPTION> $<TARGET_OBJECTS:FINGERPRINT> $<TARGET_OBJECTS:COORDINATE> $<TARGET_OBJECTS:LOGGER> $<TARGET_OBJECTS:PHANTOMNODE> $<TARGET_OBJECTS:EXCEPTION>)
add_dependencies(FINGERPRINT FingerPrintConfigure)
add_executable(osrm-routed routed.cpp ${ServerGlob})
add_executable(osrm-datastore datastore.cpp $<TARGET_OBJECTS:COORDINATE> $<TARGET_OBJECTS:FINGERPRINT> $<TARGET_OBJECTS:GITDESCRIPTION> $<TARGET_OBJECTS:LOGGER>)
add_executable(osrm-routed routed.cpp ${ServerGlob} $<TARGET_OBJECTS:EXCEPTION>)
add_executable(osrm-datastore datastore.cpp $<TARGET_OBJECTS:COORDINATE> $<TARGET_OBJECTS:FINGERPRINT> $<TARGET_OBJECTS:GITDESCRIPTION> $<TARGET_OBJECTS:LOGGER> $<TARGET_OBJECTS:EXCEPTION>)
# Unit tests
add_executable(datastructure-tests EXCLUDE_FROM_ALL UnitTests/datastructure_tests.cpp ${DataStructureTestsGlob} $<TARGET_OBJECTS:COORDINATE> $<TARGET_OBJECTS:LOGGER>)
add_executable(datastructure-tests EXCLUDE_FROM_ALL UnitTests/datastructure_tests.cpp ${DataStructureTestsGlob} $<TARGET_OBJECTS:COORDINATE> $<TARGET_OBJECTS:LOGGER> $<TARGET_OBJECTS:PHANTOMNODE> $<TARGET_OBJECTS:EXCEPTION>)
add_executable(algorithm-tests EXCLUDE_FROM_ALL UnitTests/algorithm_tests.cpp ${AlgorithmTestsGlob} $<TARGET_OBJECTS:COORDINATE> $<TARGET_OBJECTS:LOGGER> $<TARGET_OBJECTS:PHANTOMNODE> $<TARGET_OBJECTS:EXCEPTION>)
# Benchmarks
add_executable(rtree-bench EXCLUDE_FROM_ALL Benchmarks/StaticRTreeBench.cpp $<TARGET_OBJECTS:COORDINATE> $<TARGET_OBJECTS:LOGGER>)
add_executable(rtree-bench EXCLUDE_FROM_ALL benchmarks/static_rtree.cpp $<TARGET_OBJECTS:COORDINATE> $<TARGET_OBJECTS:LOGGER> $<TARGET_OBJECTS:PHANTOMNODE> $<TARGET_OBJECTS:EXCEPTION>)
# Check the release mode
if(NOT CMAKE_BUILD_TYPE MATCHES Debug)
@ -133,10 +140,16 @@ endif()
# Configuring compilers
if("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang")
# using Clang
# -Weverything -Wno-c++98-compat -Wno-shadow -Wno-exit-time-destructors
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wunreachable-code -pedantic -fPIC")
elseif("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU")
set(COLOR_FLAG "-fdiagnostics-color=auto")
CHECK_CXX_COMPILER_FLAG("-fdiagnostics-color=auto" HAS_COLOR_FLAG)
if(NOT HAS_COLOR_FLAG)
set(COLOR_FLAG "")
endif()
# using GCC
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -pedantic -fPIC")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -pedantic -fPIC ${COLOR_FLAG}")
if (WIN32) # using mingw
add_definitions(-D_USE_MATH_DEFINES) # define M_PI, M_1_PI etc.
add_definitions(-DWIN32)
@ -152,6 +165,9 @@ elseif("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC")
add_definitions(-DNOMINMAX) # avoid min and max macros that can break compilation
add_definitions(-D_USE_MATH_DEFINES) # define M_PI
add_definitions(-D_WIN32_WINNT=0x0501)
add_definitions(-DXML_STATIC)
find_library(ws2_32_LIBRARY_PATH ws2_32)
target_link_libraries(osrm-extract wsock32 ws2_32)
endif()
# Activate C++11
@ -194,6 +210,7 @@ target_link_libraries(osrm-prepare ${Boost_LIBRARIES})
target_link_libraries(osrm-routed ${Boost_LIBRARIES} ${OPTIONAL_SOCKET_LIBS} OSRM)
target_link_libraries(osrm-datastore ${Boost_LIBRARIES})
target_link_libraries(datastructure-tests ${Boost_LIBRARIES})
target_link_libraries(algorithm-tests ${Boost_LIBRARIES} ${OPTIONAL_SOCKET_LIBS} OSRM)
target_link_libraries(rtree-bench ${Boost_LIBRARIES})
find_package(Threads REQUIRED)
@ -202,6 +219,7 @@ target_link_libraries(osrm-datastore ${CMAKE_THREAD_LIBS_INIT})
target_link_libraries(osrm-prepare ${CMAKE_THREAD_LIBS_INIT})
target_link_libraries(OSRM ${CMAKE_THREAD_LIBS_INIT})
target_link_libraries(datastructure-tests ${CMAKE_THREAD_LIBS_INIT})
target_link_libraries(algorithm-tests ${CMAKE_THREAD_LIBS_INIT})
target_link_libraries(rtree-bench ${CMAKE_THREAD_LIBS_INIT})
find_package(TBB REQUIRED)
@ -213,6 +231,7 @@ target_link_libraries(osrm-extract ${TBB_LIBRARIES})
target_link_libraries(osrm-prepare ${TBB_LIBRARIES})
target_link_libraries(osrm-routed ${TBB_LIBRARIES})
target_link_libraries(datastructure-tests ${TBB_LIBRARIES})
target_link_libraries(algorithm-tests ${TBB_LIBRARIES})
target_link_libraries(rtree-bench ${TBB_LIBRARIES})
include_directories(${TBB_INCLUDE_DIR})
@ -232,9 +251,9 @@ else()
endif()
include_directories(${LUA_INCLUDE_DIR})
find_package(LibXml2 REQUIRED)
include_directories(${LIBXML2_INCLUDE_DIR})
target_link_libraries(osrm-extract ${LIBXML2_LIBRARIES})
find_package(EXPAT REQUIRED)
include_directories(${EXPAT_INCLUDE_DIRS})
target_link_libraries(osrm-extract ${EXPAT_LIBRARIES})
find_package( STXXL REQUIRED )
include_directories(${STXXL_INCLUDE_DIR})
@ -242,6 +261,11 @@ target_link_libraries(OSRM ${STXXL_LIBRARY})
target_link_libraries(osrm-extract ${STXXL_LIBRARY})
target_link_libraries(osrm-prepare ${STXXL_LIBRARY})
if(MINGW)
# STXXL needs OpenMP library
target_link_libraries(osrm-extract gomp)
endif()
find_package( OSMPBF REQUIRED )
include_directories(${OSMPBF_INCLUDE_DIR})
target_link_libraries(osrm-extract ${OSMPBF_LIBRARY})
@ -265,7 +289,7 @@ if(WITH_TOOLS OR BUILD_TOOLS)
message(STATUS "Activating OSRM internal tools")
find_package(GDAL)
if(GDAL_FOUND)
add_executable(osrm-components Tools/components.cpp $<TARGET_OBJECTS:FINGERPRINT> $<TARGET_OBJECTS:IMPORT> $<TARGET_OBJECTS:COORDINATE> $<TARGET_OBJECTS:LOGGER>)
add_executable(osrm-components tools/components.cpp $<TARGET_OBJECTS:FINGERPRINT> $<TARGET_OBJECTS:IMPORT> $<TARGET_OBJECTS:COORDINATE> $<TARGET_OBJECTS:LOGGER> $<TARGET_OBJECTS:RESTRICTION> $<TARGET_OBJECTS:EXCEPTION>)
target_link_libraries(osrm-components ${TBB_LIBRARIES})
include_directories(${GDAL_INCLUDE_DIR})
target_link_libraries(
@ -275,19 +299,19 @@ if(WITH_TOOLS OR BUILD_TOOLS)
else()
message(FATAL_ERROR "libgdal and/or development headers not found")
endif()
add_executable(osrm-cli Tools/simpleclient.cpp $<TARGET_OBJECTS:LOGGER>)
add_executable(osrm-cli tools/simpleclient.cpp $<TARGET_OBJECTS:EXCEPTION> $<TARGET_OBJECTS:LOGGER>)
target_link_libraries(osrm-cli ${Boost_LIBRARIES} ${OPTIONAL_SOCKET_LIBS} OSRM)
target_link_libraries(osrm-cli ${TBB_LIBRARIES})
add_executable(osrm-io-benchmark Tools/io-benchmark.cpp $<TARGET_OBJECTS:GITDESCRIPTION> $<TARGET_OBJECTS:LOGGER>)
add_executable(osrm-io-benchmark tools/io-benchmark.cpp $<TARGET_OBJECTS:EXCEPTION> $<TARGET_OBJECTS:GITDESCRIPTION> $<TARGET_OBJECTS:LOGGER>)
target_link_libraries(osrm-io-benchmark ${Boost_LIBRARIES})
add_executable(osrm-unlock-all Tools/unlock_all_mutexes.cpp $<TARGET_OBJECTS:GITDESCRIPTION> $<TARGET_OBJECTS:LOGGER>)
add_executable(osrm-unlock-all tools/unlock_all_mutexes.cpp $<TARGET_OBJECTS:GITDESCRIPTION> $<TARGET_OBJECTS:LOGGER> $<TARGET_OBJECTS:EXCEPTION>)
target_link_libraries(osrm-unlock-all ${Boost_LIBRARIES} ${CMAKE_THREAD_LIBS_INIT})
if(UNIX AND NOT APPLE)
target_link_libraries(osrm-unlock-all rt)
endif()
add_executable(osrm-check-hsgr Tools/check-hsgr.cpp $<TARGET_OBJECTS:FINGERPRINT> $<TARGET_OBJECTS:LOGGER>)
add_executable(osrm-check-hsgr tools/check-hsgr.cpp $<TARGET_OBJECTS:EXCEPTION> $<TARGET_OBJECTS:FINGERPRINT> $<TARGET_OBJECTS:LOGGER>)
target_link_libraries(osrm-check-hsgr ${Boost_LIBRARIES})
add_executable(osrm-springclean Tools/springclean.cpp $<TARGET_OBJECTS:FINGERPRINT> $<TARGET_OBJECTS:LOGGER> $<TARGET_OBJECTS:GITDESCRIPTION>)
add_executable(osrm-springclean tools/springclean.cpp $<TARGET_OBJECTS:FINGERPRINT> $<TARGET_OBJECTS:LOGGER> $<TARGET_OBJECTS:GITDESCRIPTION> $<TARGET_OBJECTS:EXCEPTION>)
target_link_libraries(osrm-springclean ${Boost_LIBRARIES})
install(TARGETS osrm-cli DESTINATION bin)

View File

@ -1,181 +0,0 @@
/*
Copyright (c) 2013, Project OSRM, Dennis Luxen, others
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
Redistributions of source code must retain the above copyright notice, this list
of conditions and the following disclaimer.
Redistributions in binary form must reproduce the above copyright notice, this
list of conditions and the following disclaimer in the documentation and/or
other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef PHANTOM_NODES_H
#define PHANTOM_NODES_H
#include <osrm/Coordinate.h>
#include "../DataStructures/TravelMode.h"
#include "../Util/simple_logger.hpp"
#include "../typedefs.h"
#include <vector>
struct PhantomNode
{
PhantomNode(NodeID forward_node_id, NodeID reverse_node_id, unsigned name_id,
int forward_weight, int reverse_weight, int forward_offset, int reverse_offset,
unsigned packed_geometry_id, FixedPointCoordinate &location,
unsigned short fwd_segment_position,
TravelMode forward_travel_mode, TravelMode backward_travel_mode) :
forward_node_id(forward_node_id),
reverse_node_id(reverse_node_id),
name_id(name_id),
forward_weight(forward_weight),
reverse_weight(reverse_weight),
forward_offset(forward_offset),
reverse_offset(reverse_offset),
packed_geometry_id(packed_geometry_id),
location(location),
fwd_segment_position(fwd_segment_position),
forward_travel_mode(forward_travel_mode),
backward_travel_mode(backward_travel_mode)
{ }
PhantomNode() :
forward_node_id(SPECIAL_NODEID),
reverse_node_id(SPECIAL_NODEID),
name_id(std::numeric_limits<unsigned>::max()),
forward_weight(INVALID_EDGE_WEIGHT),
reverse_weight(INVALID_EDGE_WEIGHT),
forward_offset(0),
reverse_offset(0),
packed_geometry_id(SPECIAL_EDGEID),
fwd_segment_position(0),
forward_travel_mode(TRAVEL_MODE_INACCESSIBLE),
backward_travel_mode(TRAVEL_MODE_INACCESSIBLE)
{ }
NodeID forward_node_id;
NodeID reverse_node_id;
unsigned name_id;
int forward_weight;
int reverse_weight;
int forward_offset;
int reverse_offset;
unsigned packed_geometry_id;
FixedPointCoordinate location;
unsigned short fwd_segment_position;
TravelMode forward_travel_mode : 4;
TravelMode backward_travel_mode : 4;
int GetForwardWeightPlusOffset() const
{
if (SPECIAL_NODEID == forward_node_id)
{
return 0;
}
const int result = (forward_offset + forward_weight);
return result;
}
int GetReverseWeightPlusOffset() const
{
if (SPECIAL_NODEID == reverse_node_id)
{
return 0;
}
const int result = (reverse_offset + reverse_weight);
return result;
}
bool isBidirected() const
{
return (forward_node_id != SPECIAL_NODEID) &&
(reverse_node_id != SPECIAL_NODEID);
}
bool IsCompressed() const
{
return (forward_offset != 0) || (reverse_offset != 0);
}
bool isValid(const unsigned numberOfNodes) const
{
return
location.isValid() &&
(
(forward_node_id < numberOfNodes) ||
(reverse_node_id < numberOfNodes)
) &&
(
(forward_weight != INVALID_EDGE_WEIGHT) ||
(reverse_weight != INVALID_EDGE_WEIGHT)
) &&
(name_id != std::numeric_limits<unsigned>::max()
);
}
bool isValid() const
{
return location.isValid() &&
(name_id != std::numeric_limits<unsigned>::max());
}
bool operator==(const PhantomNode & other) const
{
return location == other.location;
}
};
using PhantomNodeArray = std::vector<std::vector<PhantomNode>>;
struct PhantomNodeLists
{
std::vector<PhantomNode> source_phantom_list;
std::vector<PhantomNode> target_phantom_list;
};
struct PhantomNodes
{
PhantomNode source_phantom;
PhantomNode target_phantom;
};
inline std::ostream& operator<<(std::ostream &out, const PhantomNodes & pn)
{
out << "source_coord: " << pn.source_phantom.location << "\n";
out << "target_coord: " << pn.target_phantom.location << std::endl;
return out;
}
inline std::ostream& operator<<(std::ostream &out, const PhantomNode & pn)
{
out << "node1: " << pn.forward_node_id << ", " <<
"node2: " << pn.reverse_node_id << ", " <<
"name: " << pn.name_id << ", " <<
"fwd-w: " << pn.forward_weight << ", " <<
"rev-w: " << pn.reverse_weight << ", " <<
"fwd-o: " << pn.forward_offset << ", " <<
"rev-o: " << pn.reverse_offset << ", " <<
"geom: " << pn.packed_geometry_id << ", " <<
"pos: " << pn.fwd_segment_position << ", " <<
"loc: " << pn.location;
return out;
}
#endif // PHANTOM_NODES_H

View File

@ -1,3 +0,0 @@
The javascript based web client is a seperate project available at
https://github.com/DennisSchiefer/Project-OSRM-Web

View File

@ -1,140 +0,0 @@
/*
Copyright (c) 2013, Project OSRM, Dennis Luxen, others
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
Redistributions of source code must retain the above copyright notice, this list
of conditions and the following disclaimer.
Redistributions in binary form must reproduce the above copyright notice, this
list of conditions and the following disclaimer in the documentation and/or
other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "BaseParser.h"
#include "ExtractionWay.h"
#include "ScriptingEnvironment.h"
#include "../DataStructures/ImportNode.h"
#include "../Util/LuaUtil.h"
#include "../Util/OSRMException.h"
#include "../Util/simple_logger.hpp"
#include <boost/algorithm/string.hpp>
#include <boost/algorithm/string/regex.hpp>
#include <boost/ref.hpp>
#include <boost/regex.hpp>
BaseParser::BaseParser(ExtractorCallbacks *extractor_callbacks,
ScriptingEnvironment &scripting_environment)
: extractor_callbacks(extractor_callbacks),
lua_state(scripting_environment.getLuaState()),
scripting_environment(scripting_environment), use_turn_restrictions(true)
{
ReadUseRestrictionsSetting();
ReadRestrictionExceptions();
}
void BaseParser::ReadUseRestrictionsSetting()
{
if (0 != luaL_dostring(lua_state, "return use_turn_restrictions\n"))
{
use_turn_restrictions = false;
}
else if (lua_isboolean(lua_state, -1))
{
use_turn_restrictions = lua_toboolean(lua_state, -1);
}
if (use_turn_restrictions)
{
SimpleLogger().Write() << "Using turn restrictions";
}
else
{
SimpleLogger().Write() << "Ignoring turn restrictions";
}
}
void BaseParser::ReadRestrictionExceptions()
{
if (lua_function_exists(lua_state, "get_exceptions"))
{
// get list of turn restriction exceptions
luabind::call_function<void>(
lua_state, "get_exceptions", boost::ref(restriction_exceptions));
const unsigned exception_count = restriction_exceptions.size();
SimpleLogger().Write() << "Found " << exception_count
<< " exceptions to turn restrictions:";
for (const std::string &str : restriction_exceptions)
{
SimpleLogger().Write() << " " << str;
}
}
else
{
SimpleLogger().Write() << "Found no exceptions to turn restrictions";
}
}
void BaseParser::report_errors(lua_State *lua_state, const int status) const
{
if (0 != status)
{
std::cerr << "-- " << lua_tostring(lua_state, -1) << std::endl;
lua_pop(lua_state, 1); // remove error message
}
}
void BaseParser::ParseNodeInLua(ImportNode &node, lua_State *local_lua_state)
{
luabind::call_function<void>(local_lua_state, "node_function", boost::ref(node));
}
void BaseParser::ParseWayInLua(ExtractionWay &way, lua_State *local_lua_state)
{
luabind::call_function<void>(local_lua_state, "way_function", boost::ref(way));
}
bool BaseParser::ShouldIgnoreRestriction(const std::string &except_tag_string) const
{
// should this restriction be ignored? yes if there's an overlap between:
// a) the list of modes in the except tag of the restriction
// (except_tag_string), eg: except=bus;bicycle
// b) the lua profile defines a hierachy of modes,
// eg: [access, vehicle, bicycle]
if (except_tag_string.empty())
{
return false;
}
// Be warned, this is quadratic work here, but we assume that
// only a few exceptions are actually defined.
std::vector<std::string> exceptions;
boost::algorithm::split_regex(exceptions, except_tag_string, boost::regex("[;][ ]*"));
for (std::string &current_string : exceptions)
{
const auto string_iterator =
std::find(restriction_exceptions.begin(), restriction_exceptions.end(), current_string);
if (restriction_exceptions.end() != string_iterator)
{
return true;
}
}
return false;
}

View File

@ -1,302 +0,0 @@
/*
Copyright (c) 2013, Project OSRM, Dennis Luxen, others
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
Redistributions of source code must retain the above copyright notice, this list
of conditions and the following disclaimer.
Redistributions in binary form must reproduce the above copyright notice, this
list of conditions and the following disclaimer in the documentation and/or
other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "Extractor.h"
#include "ExtractorCallbacks.h"
#include "ExtractionContainers.h"
#include "PBFParser.h"
#include "ScriptingEnvironment.h"
#include "XMLParser.h"
#include "../Util/GitDescription.h"
#include "../Util/IniFileUtil.h"
#include "../Util/OSRMException.h"
#include "../Util/simple_logger.hpp"
#include "../Util/TimingUtil.h"
#include "../typedefs.h"
#include <boost/program_options.hpp>
#include <tbb/task_scheduler_init.h>
#include <cstdlib>
#include <chrono>
#include <fstream>
#include <iostream>
#include <thread>
#include <unordered_map>
Extractor::Extractor() : requested_num_threads(0), file_has_pbf_format(false)
{
}
Extractor::~Extractor() {}
bool Extractor::ParseArguments(int argc, char *argv[])
{
// declare a group of options that will be allowed only on command line
boost::program_options::options_description generic_options("Options");
generic_options.add_options()("version,v", "Show version")("help,h", "Show this help message")(
"config,c",
boost::program_options::value<boost::filesystem::path>(&config_file_path)
->default_value("extractor.ini"),
"Path to a configuration file.");
// declare a group of options that will be allowed both on command line and in config file
boost::program_options::options_description config_options("Configuration");
config_options.add_options()("profile,p",
boost::program_options::value<boost::filesystem::path>(
&profile_path)->default_value("profile.lua"),
"Path to LUA routing profile")(
"threads,t",
boost::program_options::value<unsigned int>(&requested_num_threads)
->default_value(tbb::task_scheduler_init::default_num_threads()),
"Number of threads to use");
// hidden options, will be allowed both on command line and in config file, but will not be
// shown to the user
boost::program_options::options_description hidden_options("Hidden options");
hidden_options.add_options()(
"input,i",
boost::program_options::value<boost::filesystem::path>(&input_path),
"Input file in .osm, .osm.bz2 or .osm.pbf format");
// positional option
boost::program_options::positional_options_description positional_options;
positional_options.add("input", 1);
// combine above options for parsing
boost::program_options::options_description cmdline_options;
cmdline_options.add(generic_options).add(config_options).add(hidden_options);
boost::program_options::options_description config_file_options;
config_file_options.add(config_options).add(hidden_options);
boost::program_options::options_description visible_options(
boost::filesystem::basename(argv[0]) + " <input.osm/.osm.bz2/.osm.pbf> [options]");
visible_options.add(generic_options).add(config_options);
// parse command line options
boost::program_options::variables_map option_variables;
boost::program_options::store(boost::program_options::command_line_parser(argc, argv)
.options(cmdline_options)
.positional(positional_options)
.run(),
option_variables);
if (option_variables.count("version"))
{
SimpleLogger().Write() << g_GIT_DESCRIPTION;
return false;
}
if (option_variables.count("help"))
{
SimpleLogger().Write() << visible_options;
return false;
}
boost::program_options::notify(option_variables);
// parse config file
if (boost::filesystem::is_regular_file(config_file_path))
{
SimpleLogger().Write() << "Reading options from: " << config_file_path.string();
std::string ini_file_contents = ReadIniFileAndLowerContents(config_file_path);
std::stringstream config_stream(ini_file_contents);
boost::program_options::store(parse_config_file(config_stream, config_file_options),
option_variables);
boost::program_options::notify(option_variables);
}
if (!option_variables.count("input"))
{
SimpleLogger().Write() << visible_options;
return false;
}
return true;
}
void Extractor::GenerateOutputFilesNames()
{
output_file_name = input_path.string();
restriction_file_name = input_path.string();
std::string::size_type pos = output_file_name.find(".osm.bz2");
if (pos == std::string::npos)
{
pos = output_file_name.find(".osm.pbf");
if (pos != std::string::npos)
{
file_has_pbf_format = true;
}
else
{
pos = output_file_name.find(".osm.xml");
}
}
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)
{
pos = output_file_name.find(".osm");
if (pos == std::string::npos)
{
output_file_name.append(".osrm");
restriction_file_name.append(".osrm.restrictions");
}
else
{
output_file_name.replace(pos, 5, ".osrm");
restriction_file_name.replace(pos, 5, ".osrm.restrictions");
}
}
else
{
output_file_name.replace(pos, 8, ".osrm");
restriction_file_name.replace(pos, 8, ".osrm.restrictions");
}
}
int Extractor::Run(int argc, char *argv[])
{
try
{
LogPolicy::GetInstance().Unmute();
TIMER_START(extracting);
if (!ParseArguments(argc, argv))
return 0;
if (1 > requested_num_threads)
{
SimpleLogger().Write(logWARNING) << "Number of threads must be 1 or larger";
return 1;
}
if (!boost::filesystem::is_regular_file(input_path))
{
SimpleLogger().Write(logWARNING) << "Input file " << input_path.string()
<< " not found!";
return 1;
}
if (!boost::filesystem::is_regular_file(profile_path))
{
SimpleLogger().Write(logWARNING) << "Profile " << profile_path.string()
<< " not found!";
return 1;
}
const unsigned recommended_num_threads = tbb::task_scheduler_init::default_num_threads();
SimpleLogger().Write() << "Input file: " << input_path.filename().string();
SimpleLogger().Write() << "Profile: " << profile_path.filename().string();
SimpleLogger().Write() << "Threads: " << requested_num_threads;
if (recommended_num_threads != requested_num_threads)
{
SimpleLogger().Write(logWARNING) << "The recommended number of threads is "
<< recommended_num_threads
<< "! This setting may have performance side-effects.";
}
tbb::task_scheduler_init init(requested_num_threads);
/*** Setup Scripting Environment ***/
ScriptingEnvironment scripting_environment(profile_path.string().c_str());
GenerateOutputFilesNames();
std::unordered_map<std::string, NodeID> string_map;
ExtractionContainers extraction_containers;
string_map[""] = 0;
auto extractor_callbacks = new ExtractorCallbacks(extraction_containers, string_map);
BaseParser *parser;
if (file_has_pbf_format)
{
parser = new PBFParser(input_path.string().c_str(),
extractor_callbacks,
scripting_environment,
requested_num_threads);
}
else
{
parser = new XMLParser(input_path.string().c_str(),
extractor_callbacks,
scripting_environment);
}
if (!parser->ReadHeader())
{
throw OSRMException("Parser not initialized!");
}
SimpleLogger().Write() << "Parsing in progress..";
TIMER_START(parsing);
parser->Parse();
delete parser;
delete extractor_callbacks;
TIMER_STOP(parsing);
SimpleLogger().Write() << "Parsing finished after " << TIMER_SEC(parsing) << " seconds";
if (extraction_containers.all_edges_list.empty())
{
SimpleLogger().Write(logWARNING) << "The input data is empty, exiting.";
return 1;
}
extraction_containers.PrepareData(output_file_name, restriction_file_name);
TIMER_STOP(extracting);
SimpleLogger().Write() << "extraction finished after " << TIMER_SEC(extracting) << "s";
SimpleLogger().Write() << "To prepare the data for routing, run: "
<< "./osrm-prepare " << output_file_name << std::endl;
}
catch (boost::program_options::too_many_positional_options_error &)
{
SimpleLogger().Write(logWARNING) << "Only one input file can be specified";
return 1;
}
catch (std::exception &e)
{
SimpleLogger().Write(logWARNING) << e.what();
return 1;
}
return 0;
}

View File

@ -1,36 +0,0 @@
#ifndef EXTRACTOR_H_
#define EXTRACTOR_H_
#include <boost/filesystem.hpp>
#include <string>
class ExtractorCallbacks;
/** \brief Class of 'extract' utility. */
class Extractor
{
protected:
unsigned requested_num_threads;
boost::filesystem::path config_file_path;
boost::filesystem::path input_path;
boost::filesystem::path profile_path;
std::string output_file_name;
std::string restriction_file_name;
bool file_has_pbf_format;
/** \brief Parses "extractor's" command line arguments */
bool ParseArguments(int argc, char *argv[]);
/** \brief Parses config file, if present in options */
void GenerateOutputFilesNames();
public:
explicit Extractor();
Extractor(const Extractor &) = delete;
virtual ~Extractor();
int Run(int argc, char *argv[]);
};
#endif /* EXTRACTOR_H_ */

View File

@ -1,182 +0,0 @@
/*
Copyright (c) 2013, Project OSRM, Dennis Luxen, others
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
Redistributions of source code must retain the above copyright notice, this list
of conditions and the following disclaimer.
Redistributions in binary form must reproduce the above copyright notice, this
list of conditions and the following disclaimer in the documentation and/or
other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "ExtractorCallbacks.h"
#include "ExtractionContainers.h"
#include "ExtractionWay.h"
#include "../DataStructures/Restriction.h"
#include "../DataStructures/ImportNode.h"
#include "../Util/simple_logger.hpp"
#include <osrm/Coordinate.h>
#include <limits>
#include <string>
#include <vector>
ExtractorCallbacks::ExtractorCallbacks(ExtractionContainers &extraction_containers,
std::unordered_map<std::string, NodeID> &string_map)
: string_map(string_map), external_memory(extraction_containers)
{
}
/** warning: caller needs to take care of synchronization! */
void ExtractorCallbacks::ProcessNode(const ExternalMemoryNode &n)
{
if (n.lat <= 85 * COORDINATE_PRECISION && n.lat >= -85 * COORDINATE_PRECISION)
{
external_memory.all_nodes_list.push_back(n);
}
}
bool ExtractorCallbacks::ProcessRestriction(const InputRestrictionContainer &restriction)
{
external_memory.restrictions_list.push_back(restriction);
return true;
}
/** warning: caller needs to take care of synchronization! */
void ExtractorCallbacks::ProcessWay(ExtractionWay &parsed_way)
{
if (((0 >= parsed_way.forward_speed) ||
(TRAVEL_MODE_INACCESSIBLE == parsed_way.forward_travel_mode)) &&
((0 >= parsed_way.backward_speed) ||
(TRAVEL_MODE_INACCESSIBLE == parsed_way.backward_travel_mode)) &&
(0 >= parsed_way.duration))
{ // Only true if the way is specified by the speed profile
return;
}
if (parsed_way.path.size() <= 1)
{ // safe-guard against broken data
return;
}
if (std::numeric_limits<unsigned>::max() == parsed_way.id)
{
SimpleLogger().Write(logDEBUG) << "found bogus way with id: " << parsed_way.id
<< " of size " << parsed_way.path.size();
return;
}
if (0 < parsed_way.duration)
{
// TODO: iterate all way segments and set duration corresponding to the length of each
// segment
parsed_way.forward_speed = parsed_way.duration / (parsed_way.path.size() - 1);
parsed_way.backward_speed = parsed_way.duration / (parsed_way.path.size() - 1);
}
if (std::numeric_limits<double>::epsilon() >= std::abs(-1. - parsed_way.forward_speed))
{
SimpleLogger().Write(logDEBUG) << "found way with bogus speed, id: " << parsed_way.id;
return;
}
// Get the unique identifier for the street name
const auto &string_map_iterator = string_map.find(parsed_way.name);
if (string_map.end() == string_map_iterator)
{
parsed_way.nameID = external_memory.name_list.size();
external_memory.name_list.push_back(parsed_way.name);
string_map.insert(std::make_pair(parsed_way.name, parsed_way.nameID));
}
else
{
parsed_way.nameID = string_map_iterator->second;
}
if (TRAVEL_MODE_INACCESSIBLE == parsed_way.forward_travel_mode)
{
std::reverse(parsed_way.path.begin(), parsed_way.path.end());
parsed_way.forward_travel_mode = parsed_way.backward_travel_mode;
parsed_way.backward_travel_mode = TRAVEL_MODE_INACCESSIBLE;
}
const bool split_edge =
(parsed_way.forward_speed>0) && (TRAVEL_MODE_INACCESSIBLE != parsed_way.forward_travel_mode) &&
(parsed_way.backward_speed>0) && (TRAVEL_MODE_INACCESSIBLE != parsed_way.backward_travel_mode) &&
((parsed_way.forward_speed != parsed_way.backward_speed) ||
(parsed_way.forward_travel_mode != parsed_way.backward_travel_mode));
BOOST_ASSERT(parsed_way.forward_travel_mode>0);
for (unsigned n = 0; n < (parsed_way.path.size() - 1); ++n)
{
external_memory.all_edges_list.push_back(InternalExtractorEdge(
parsed_way.path[n],
parsed_way.path[n + 1],
((split_edge || TRAVEL_MODE_INACCESSIBLE == parsed_way.backward_travel_mode) ? ExtractionWay::oneway
: ExtractionWay::bidirectional),
parsed_way.forward_speed,
parsed_way.nameID,
parsed_way.roundabout,
parsed_way.ignoreInGrid,
(0 < parsed_way.duration),
parsed_way.isAccessRestricted,
parsed_way.forward_travel_mode,
split_edge));
external_memory.used_node_id_list.push_back(parsed_way.path[n]);
}
external_memory.used_node_id_list.push_back(parsed_way.path.back());
// The following information is needed to identify start and end segments of restrictions
external_memory.way_start_end_id_list.push_back(
WayIDStartAndEndEdge(parsed_way.id,
parsed_way.path[0],
parsed_way.path[1],
parsed_way.path[parsed_way.path.size() - 2],
parsed_way.path.back()));
if (split_edge)
{ // Only true if the way should be split
BOOST_ASSERT(parsed_way.backward_travel_mode>0);
std::reverse(parsed_way.path.begin(), parsed_way.path.end());
for (std::vector<NodeID>::size_type n = 0; n < parsed_way.path.size() - 1; ++n)
{
external_memory.all_edges_list.push_back(
InternalExtractorEdge(parsed_way.path[n],
parsed_way.path[n + 1],
ExtractionWay::oneway,
parsed_way.backward_speed,
parsed_way.nameID,
parsed_way.roundabout,
parsed_way.ignoreInGrid,
(0 < parsed_way.duration),
parsed_way.isAccessRestricted,
parsed_way.backward_travel_mode,
split_edge));
}
external_memory.way_start_end_id_list.push_back(
WayIDStartAndEndEdge(parsed_way.id,
parsed_way.path[0],
parsed_way.path[1],
parsed_way.path[parsed_way.path.size() - 2],
parsed_way.path.back()));
}
}

View File

@ -1,114 +0,0 @@
/*
Copyright (c) 2013, Project OSRM, Dennis Luxen, others
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
Redistributions of source code must retain the above copyright notice, this list
of conditions and the following disclaimer.
Redistributions in binary form must reproduce the above copyright notice, this
list of conditions and the following disclaimer in the documentation and/or
other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef EXTRACTORSTRUCTS_H_
#define EXTRACTORSTRUCTS_H_
#include "../DataStructures/HashTable.h"
#include "../DataStructures/ImportNode.h"
#include "../typedefs.h"
#include <limits>
#include <string>
struct ExtractorRelation
{
ExtractorRelation() : type(unknown) {}
enum
{ unknown = 0,
ferry,
turnRestriction } type;
HashTable<std::string, std::string> keyVals;
};
struct WayIDStartAndEndEdge
{
unsigned wayID;
NodeID firstStart;
NodeID firstTarget;
NodeID lastStart;
NodeID lastTarget;
WayIDStartAndEndEdge()
: wayID(std::numeric_limits<unsigned>::max()), firstStart(std::numeric_limits<unsigned>::max()), firstTarget(std::numeric_limits<unsigned>::max()), lastStart(std::numeric_limits<unsigned>::max()),
lastTarget(std::numeric_limits<unsigned>::max())
{
}
explicit WayIDStartAndEndEdge(unsigned w, NodeID fs, NodeID ft, NodeID ls, NodeID lt)
: wayID(w), firstStart(fs), firstTarget(ft), lastStart(ls), lastTarget(lt)
{
}
static WayIDStartAndEndEdge min_value()
{
return WayIDStartAndEndEdge((std::numeric_limits<unsigned>::min)(),
(std::numeric_limits<unsigned>::min)(),
(std::numeric_limits<unsigned>::min)(),
(std::numeric_limits<unsigned>::min)(),
(std::numeric_limits<unsigned>::min)());
}
static WayIDStartAndEndEdge max_value()
{
return WayIDStartAndEndEdge((std::numeric_limits<unsigned>::max)(),
(std::numeric_limits<unsigned>::max)(),
(std::numeric_limits<unsigned>::max)(),
(std::numeric_limits<unsigned>::max)(),
(std::numeric_limits<unsigned>::max)());
}
};
struct CmpWayByID
{
using value_type = WayIDStartAndEndEdge;
bool operator()(const WayIDStartAndEndEdge &a, const WayIDStartAndEndEdge &b) const
{
return a.wayID < b.wayID;
}
value_type max_value() { return WayIDStartAndEndEdge::max_value(); }
value_type min_value() { return WayIDStartAndEndEdge::min_value(); }
};
struct Cmp
{
using value_type = NodeID;
bool operator()(const NodeID left, const NodeID right) const { return left < right; }
value_type max_value() { return 0xffffffff; }
value_type min_value() { return 0x0; }
};
struct CmpNodeByID
{
using value_type = ExternalMemoryNode;
bool operator()(const ExternalMemoryNode &left, const ExternalMemoryNode &right) const
{
return left.node_id < right.node_id;
}
value_type max_value() { return ExternalMemoryNode::max_value(); }
value_type min_value() { return ExternalMemoryNode::min_value(); }
};
#endif /* EXTRACTORSTRUCTS_H_ */

View File

@ -1,665 +0,0 @@
/*
Copyright (c) 2013, Project OSRM, Dennis Luxen, others
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
Redistributions of source code must retain the above copyright notice, this list
of conditions and the following disclaimer.
Redistributions in binary form must reproduce the above copyright notice, this
list of conditions and the following disclaimer in the documentation and/or
other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "PBFParser.h"
#include "ExtractionWay.h"
#include "ExtractorCallbacks.h"
#include "ScriptingEnvironment.h"
#include "../DataStructures/HashTable.h"
#include "../DataStructures/ImportNode.h"
#include "../DataStructures/Restriction.h"
#include "../Util/MachineInfo.h"
#include "../Util/OSRMException.h"
#include "../Util/simple_logger.hpp"
#include "../typedefs.h"
#include <boost/assert.hpp>
#include <tbb/parallel_for.h>
#include <tbb/task_scheduler_init.h>
#include <osrm/Coordinate.h>
#include <zlib.h>
#include <functional>
#include <iostream>
#include <limits>
#include <thread>
PBFParser::PBFParser(const char *fileName,
ExtractorCallbacks *extractor_callbacks,
ScriptingEnvironment &scripting_environment,
unsigned num_threads)
: BaseParser(extractor_callbacks, scripting_environment)
{
if (0 == num_threads)
{
num_parser_threads = tbb::task_scheduler_init::default_num_threads();
}
else
{
num_parser_threads = num_threads;
}
GOOGLE_PROTOBUF_VERIFY_VERSION;
// TODO: What is the bottleneck here? Filling the queue or reading the stuff from disk?
// NOTE: With Lua scripting, it is parsing the stuff. I/O is virtually for free.
// Max 2500 items in queue, hardcoded.
thread_data_queue = std::make_shared<ConcurrentQueue<ParserThreadData *>>(2500);
input.open(fileName, std::ios::in | std::ios::binary);
if (!input)
{
throw OSRMException("pbf file not found.");
}
block_count = 0;
group_count = 0;
}
PBFParser::~PBFParser()
{
if (input.is_open())
{
input.close();
}
// Clean up any leftover ThreadData objects in the queue
ParserThreadData *thread_data;
while (thread_data_queue->try_pop(thread_data))
{
delete thread_data;
}
google::protobuf::ShutdownProtobufLibrary();
SimpleLogger().Write(logDEBUG) << "parsed " << block_count << " blocks from pbf with "
<< group_count << " groups";
}
inline bool PBFParser::ReadHeader()
{
ParserThreadData init_data;
/** read Header */
if (!readPBFBlobHeader(input, &init_data))
{
return false;
}
if (readBlob(input, &init_data))
{
if (!init_data.PBFHeaderBlock.ParseFromArray(&(init_data.charBuffer[0]),
static_cast<int>(init_data.charBuffer.size())))
{
std::cerr << "[error] Header not parseable!" << std::endl;
return false;
}
const auto feature_size = init_data.PBFHeaderBlock.required_features_size();
for (int i = 0; i < feature_size; ++i)
{
const std::string &feature = init_data.PBFHeaderBlock.required_features(i);
bool supported = false;
if ("OsmSchema-V0.6" == feature)
{
supported = true;
}
else if ("DenseNodes" == feature)
{
supported = true;
}
if (!supported)
{
std::cerr << "[error] required feature not supported: " << feature.data()
<< std::endl;
return false;
}
}
}
else
{
std::cerr << "[error] blob not loaded!" << std::endl;
}
return true;
}
inline void PBFParser::ReadData()
{
bool keep_running = true;
do
{
ParserThreadData *thread_data = new ParserThreadData();
keep_running = readNextBlock(input, thread_data);
if (keep_running)
{
thread_data_queue->push(thread_data);
}
else
{
// No more data to read, parse stops when nullptr encountered
thread_data_queue->push(nullptr);
delete thread_data;
}
} while (keep_running);
}
inline void PBFParser::ParseData()
{
tbb::task_scheduler_init init(num_parser_threads);
while (true)
{
ParserThreadData *thread_data;
thread_data_queue->wait_and_pop(thread_data);
if (nullptr == thread_data)
{
thread_data_queue->push(nullptr); // Signal end of data for other threads
break;
}
loadBlock(thread_data);
int group_size = thread_data->PBFprimitiveBlock.primitivegroup_size();
for (int i = 0; i < group_size; ++i)
{
thread_data->currentGroupID = i;
loadGroup(thread_data);
if (thread_data->entityTypeIndicator == TypeNode)
{
parseNode(thread_data);
}
if (thread_data->entityTypeIndicator == TypeWay)
{
parseWay(thread_data);
}
if (thread_data->entityTypeIndicator == TypeRelation)
{
parseRelation(thread_data);
}
if (thread_data->entityTypeIndicator == TypeDenseNode)
{
parseDenseNode(thread_data);
}
}
delete thread_data;
thread_data = nullptr;
}
}
inline bool PBFParser::Parse()
{
// Start the read and parse threads
std::thread read_thread(std::bind(&PBFParser::ReadData, this));
// Open several parse threads that are synchronized before call to
std::thread parse_thread(std::bind(&PBFParser::ParseData, this));
// Wait for the threads to finish
read_thread.join();
parse_thread.join();
return true;
}
inline void PBFParser::parseDenseNode(ParserThreadData *thread_data)
{
const OSMPBF::DenseNodes &dense =
thread_data->PBFprimitiveBlock.primitivegroup(thread_data->currentGroupID).dense();
int denseTagIndex = 0;
int64_t m_lastDenseID = 0;
int64_t m_lastDenseLatitude = 0;
int64_t m_lastDenseLongitude = 0;
const int number_of_nodes = dense.id_size();
std::vector<ImportNode> extracted_nodes_vector(number_of_nodes);
for (int i = 0; i < number_of_nodes; ++i)
{
m_lastDenseID += dense.id(i);
m_lastDenseLatitude += dense.lat(i);
m_lastDenseLongitude += dense.lon(i);
extracted_nodes_vector[i].node_id = static_cast<NodeID>(m_lastDenseID);
extracted_nodes_vector[i].lat = static_cast<int>(
COORDINATE_PRECISION *
((double)m_lastDenseLatitude * thread_data->PBFprimitiveBlock.granularity() +
thread_data->PBFprimitiveBlock.lat_offset()) /
NANO);
extracted_nodes_vector[i].lon = static_cast<int>(
COORDINATE_PRECISION *
((double)m_lastDenseLongitude * thread_data->PBFprimitiveBlock.granularity() +
thread_data->PBFprimitiveBlock.lon_offset()) /
NANO);
while (denseTagIndex < dense.keys_vals_size())
{
const int tagValue = dense.keys_vals(denseTagIndex);
if (0 == tagValue)
{
++denseTagIndex;
break;
}
const int keyValue = dense.keys_vals(denseTagIndex + 1);
const std::string &key = thread_data->PBFprimitiveBlock.stringtable().s(tagValue);
const std::string &value = thread_data->PBFprimitiveBlock.stringtable().s(keyValue);
extracted_nodes_vector[i].keyVals.Add(std::move(key), std::move(value));
denseTagIndex += 2;
}
}
tbb::parallel_for(tbb::blocked_range<size_t>(0, extracted_nodes_vector.size()),
[this, &extracted_nodes_vector](const tbb::blocked_range<size_t> &range)
{
lua_State *lua_state = this->scripting_environment.getLuaState();
for (size_t i = range.begin(); i != range.end(); ++i)
{
ImportNode &import_node = extracted_nodes_vector[i];
ParseNodeInLua(import_node, lua_state);
}
});
for (const ImportNode &import_node : extracted_nodes_vector)
{
extractor_callbacks->ProcessNode(import_node);
}
}
inline void PBFParser::parseNode(ParserThreadData *)
{
throw OSRMException("Parsing of simple nodes not supported. PBF should use dense nodes");
}
inline void PBFParser::parseRelation(ParserThreadData *thread_data)
{
// TODO: leave early, if relation is not a restriction
// TODO: reuse rawRestriction container
if (!use_turn_restrictions)
{
return;
}
const OSMPBF::PrimitiveGroup &group =
thread_data->PBFprimitiveBlock.primitivegroup(thread_data->currentGroupID);
for (int i = 0, relation_size = group.relations_size(); i < relation_size; ++i)
{
std::string except_tag_string;
const OSMPBF::Relation &inputRelation =
thread_data->PBFprimitiveBlock.primitivegroup(thread_data->currentGroupID).relations(i);
bool is_restriction = false;
bool is_only_restriction = false;
for (int k = 0, endOfKeys = inputRelation.keys_size(); k < endOfKeys; ++k)
{
const std::string &key =
thread_data->PBFprimitiveBlock.stringtable().s(inputRelation.keys(k));
const std::string &val =
thread_data->PBFprimitiveBlock.stringtable().s(inputRelation.vals(k));
if ("type" == key)
{
if ("restriction" == val)
{
is_restriction = true;
}
else
{
break;
}
}
if (("restriction" == key) && (val.find("only_") == 0))
{
is_only_restriction = true;
}
if ("except" == key)
{
except_tag_string = val;
}
}
if (is_restriction && ShouldIgnoreRestriction(except_tag_string))
{
continue;
}
if (is_restriction)
{
int64_t last_ref = 0;
InputRestrictionContainer current_restriction_container(is_only_restriction);
for (int rolesIndex = 0, last_role = inputRelation.roles_sid_size();
rolesIndex < last_role;
++rolesIndex)
{
const std::string &role = thread_data->PBFprimitiveBlock.stringtable().s(
inputRelation.roles_sid(rolesIndex));
last_ref += inputRelation.memids(rolesIndex);
if (!("from" == role || "to" == role || "via" == role))
{
continue;
}
switch (inputRelation.types(rolesIndex))
{
case 0: // node
if ("from" == role || "to" == role)
{ // Only via should be a node
continue;
}
BOOST_ASSERT("via" == role);
if (std::numeric_limits<unsigned>::max() !=
current_restriction_container.viaNode)
{
current_restriction_container.viaNode =
std::numeric_limits<unsigned>::max();
}
BOOST_ASSERT(std::numeric_limits<unsigned>::max() ==
current_restriction_container.viaNode);
current_restriction_container.restriction.viaNode =
static_cast<NodeID>(last_ref);
break;
case 1: // way
BOOST_ASSERT("from" == role || "to" == role || "via" == role);
if ("from" == role)
{
current_restriction_container.fromWay = static_cast<EdgeID>(last_ref);
}
if ("to" == role)
{
current_restriction_container.toWay = static_cast<EdgeID>(last_ref);
}
if ("via" == role)
{
BOOST_ASSERT(current_restriction_container.restriction.toNode ==
std::numeric_limits<unsigned>::max());
current_restriction_container.viaNode = static_cast<NodeID>(last_ref);
}
break;
case 2: // relation, not used. relations relating to relations are evil.
continue;
BOOST_ASSERT(false);
break;
default: // should not happen
BOOST_ASSERT(false);
break;
}
}
if (!extractor_callbacks->ProcessRestriction(current_restriction_container))
{
std::cerr << "[PBFParser] relation not parsed" << std::endl;
}
}
}
}
inline void PBFParser::parseWay(ParserThreadData *thread_data)
{
const int number_of_ways =
thread_data->PBFprimitiveBlock.primitivegroup(thread_data->currentGroupID).ways_size();
std::vector<ExtractionWay> parsed_way_vector(number_of_ways);
for (int i = 0; i < number_of_ways; ++i)
{
const OSMPBF::Way &input_way =
thread_data->PBFprimitiveBlock.primitivegroup(thread_data->currentGroupID).ways(i);
parsed_way_vector[i].id = static_cast<EdgeID>(input_way.id());
unsigned node_id_in_path = 0;
const auto number_of_referenced_nodes = input_way.refs_size();
for (auto j = 0; j < number_of_referenced_nodes; ++j)
{
node_id_in_path += static_cast<NodeID>(input_way.refs(j));
parsed_way_vector[i].path.push_back(node_id_in_path);
}
BOOST_ASSERT(input_way.keys_size() == input_way.vals_size());
const auto number_of_keys = input_way.keys_size();
for (auto j = 0; j < number_of_keys; ++j)
{
const std::string &key =
thread_data->PBFprimitiveBlock.stringtable().s(input_way.keys(j));
const std::string &val =
thread_data->PBFprimitiveBlock.stringtable().s(input_way.vals(j));
parsed_way_vector[i].keyVals.Add(std::move(key), std::move(val));
}
}
// TODO: investigate if schedule guided will be handled by tbb automatically
tbb::parallel_for(tbb::blocked_range<size_t>(0, parsed_way_vector.size()),
[this, &parsed_way_vector](const tbb::blocked_range<size_t> &range)
{
lua_State *lua_state = this->scripting_environment.getLuaState();
for (size_t i = range.begin(); i != range.end(); i++)
{
ExtractionWay &extraction_way = parsed_way_vector[i];
if (2 <= extraction_way.path.size())
{
ParseWayInLua(extraction_way, lua_state);
}
}
});
for (ExtractionWay &extraction_way : parsed_way_vector)
{
if (2 <= extraction_way.path.size())
{
extractor_callbacks->ProcessWay(extraction_way);
}
}
}
inline void PBFParser::loadGroup(ParserThreadData *thread_data)
{
#ifndef NDEBUG
++group_count;
#endif
const OSMPBF::PrimitiveGroup &group =
thread_data->PBFprimitiveBlock.primitivegroup(thread_data->currentGroupID);
thread_data->entityTypeIndicator = TypeDummy;
if (0 != group.nodes_size())
{
thread_data->entityTypeIndicator = TypeNode;
}
if (0 != group.ways_size())
{
thread_data->entityTypeIndicator = TypeWay;
}
if (0 != group.relations_size())
{
thread_data->entityTypeIndicator = TypeRelation;
}
if (group.has_dense())
{
thread_data->entityTypeIndicator = TypeDenseNode;
BOOST_ASSERT(0 != group.dense().id_size());
}
BOOST_ASSERT(thread_data->entityTypeIndicator != TypeDummy);
}
inline void PBFParser::loadBlock(ParserThreadData *thread_data)
{
++block_count;
thread_data->currentGroupID = 0;
thread_data->currentEntityID = 0;
}
inline bool PBFParser::readPBFBlobHeader(std::fstream &stream, ParserThreadData *thread_data)
{
int size(0);
stream.read((char *)&size, sizeof(int));
size = SwapEndian(size);
if (stream.eof())
{
return false;
}
if (size > MAX_BLOB_HEADER_SIZE || size < 0)
{
return false;
}
char *data = new char[size];
stream.read(data, size * sizeof(data[0]));
bool dataSuccessfullyParsed = (thread_data->PBFBlobHeader).ParseFromArray(data, size);
delete[] data;
return dataSuccessfullyParsed;
}
inline bool PBFParser::unpackZLIB(ParserThreadData *thread_data)
{
auto raw_size = thread_data->PBFBlob.raw_size();
char *unpacked_data_array = new char[raw_size];
z_stream compressed_data_stream;
compressed_data_stream.next_in = (unsigned char *)thread_data->PBFBlob.zlib_data().data();
compressed_data_stream.avail_in = thread_data->PBFBlob.zlib_data().size();
compressed_data_stream.next_out = (unsigned char *)unpacked_data_array;
compressed_data_stream.avail_out = raw_size;
compressed_data_stream.zalloc = Z_NULL;
compressed_data_stream.zfree = Z_NULL;
compressed_data_stream.opaque = Z_NULL;
int return_code = inflateInit(&compressed_data_stream);
if (return_code != Z_OK)
{
std::cerr << "[error] failed to init zlib stream" << std::endl;
delete[] unpacked_data_array;
return false;
}
return_code = inflate(&compressed_data_stream, Z_FINISH);
if (return_code != Z_STREAM_END)
{
std::cerr << "[error] failed to inflate zlib stream" << std::endl;
std::cerr << "[error] Error type: " << return_code << std::endl;
delete[] unpacked_data_array;
return false;
}
return_code = inflateEnd(&compressed_data_stream);
if (return_code != Z_OK)
{
std::cerr << "[error] failed to deinit zlib stream" << std::endl;
delete[] unpacked_data_array;
return false;
}
thread_data->charBuffer.clear();
thread_data->charBuffer.resize(raw_size);
std::copy(unpacked_data_array, unpacked_data_array + raw_size, thread_data->charBuffer.begin());
delete[] unpacked_data_array;
return true;
}
inline bool PBFParser::unpackLZMA(ParserThreadData *) { return false; }
inline bool PBFParser::readBlob(std::fstream &stream, ParserThreadData *thread_data)
{
if (stream.eof())
{
return false;
}
const int size = thread_data->PBFBlobHeader.datasize();
if (size < 0 || size > MAX_BLOB_SIZE)
{
std::cerr << "[error] invalid Blob size:" << size << std::endl;
return false;
}
char *data = new char[size];
stream.read(data, sizeof(data[0]) * size);
if (!thread_data->PBFBlob.ParseFromArray(data, size))
{
std::cerr << "[error] failed to parse blob" << std::endl;
delete[] data;
return false;
}
if (thread_data->PBFBlob.has_raw())
{
const std::string &data = thread_data->PBFBlob.raw();
thread_data->charBuffer.clear();
thread_data->charBuffer.resize(data.size());
std::copy(data.begin(), data.end(), thread_data->charBuffer.begin());
}
else if (thread_data->PBFBlob.has_zlib_data())
{
if (!unpackZLIB(thread_data))
{
std::cerr << "[error] zlib data encountered that could not be unpacked" << std::endl;
delete[] data;
return false;
}
}
else if (thread_data->PBFBlob.has_lzma_data())
{
if (!unpackLZMA(thread_data))
{
std::cerr << "[error] lzma data encountered that could not be unpacked" << std::endl;
}
delete[] data;
return false;
}
else
{
std::cerr << "[error] Blob contains no data" << std::endl;
delete[] data;
return false;
}
delete[] data;
return true;
}
bool PBFParser::readNextBlock(std::fstream &stream, ParserThreadData *thread_data)
{
if (stream.eof())
{
return false;
}
if (!readPBFBlobHeader(stream, thread_data))
{
return false;
}
if (thread_data->PBFBlobHeader.type() != "OSMData")
{
return false;
}
if (!readBlob(stream, thread_data))
{
return false;
}
if (!thread_data->PBFprimitiveBlock.ParseFromArray(&(thread_data->charBuffer[0]),
thread_data->charBuffer.size()))
{
std::cerr << "failed to parse PrimitiveBlock" << std::endl;
return false;
}
return true;
}

View File

@ -1,103 +0,0 @@
/*
Copyright (c) 2013, Project OSRM, Dennis Luxen, others
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
Redistributions of source code must retain the above copyright notice, this list
of conditions and the following disclaimer.
Redistributions in binary form must reproduce the above copyright notice, this
list of conditions and the following disclaimer in the documentation and/or
other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef PBFPARSER_H_
#define PBFPARSER_H_
#include "BaseParser.h"
#include "../DataStructures/ConcurrentQueue.h"
#include <osmpbf/fileformat.pb.h>
#include <osmpbf/osmformat.pb.h>
#include <fstream>
#include <memory>
class PBFParser : public BaseParser
{
enum EntityType
{ TypeDummy = 0,
TypeNode = 1,
TypeWay = 2,
TypeRelation = 4,
TypeDenseNode = 8 };
struct ParserThreadData
{
int currentGroupID;
int currentEntityID;
EntityType entityTypeIndicator;
OSMPBF::BlobHeader PBFBlobHeader;
OSMPBF::Blob PBFBlob;
OSMPBF::HeaderBlock PBFHeaderBlock;
OSMPBF::PrimitiveBlock PBFprimitiveBlock;
std::vector<char> charBuffer;
};
public:
PBFParser(const char *file_name,
ExtractorCallbacks *extractor_callbacks,
ScriptingEnvironment &scripting_environment,
unsigned num_parser_threads = 0);
virtual ~PBFParser();
inline bool ReadHeader();
inline bool Parse();
private:
inline void ReadData();
inline void ParseData();
inline void parseDenseNode(ParserThreadData *thread_data);
inline void parseNode(ParserThreadData *thread_data);
inline void parseRelation(ParserThreadData *thread_data);
inline void parseWay(ParserThreadData *thread_data);
inline void loadGroup(ParserThreadData *thread_data);
inline void loadBlock(ParserThreadData *thread_data);
inline bool readPBFBlobHeader(std::fstream &stream, ParserThreadData *thread_data);
inline bool unpackZLIB(ParserThreadData *thread_data);
inline bool unpackLZMA(ParserThreadData *thread_data);
inline bool readBlob(std::fstream &stream, ParserThreadData *thread_data);
inline bool readNextBlock(std::fstream &stream, ParserThreadData *thread_data);
static const int NANO = 1000 * 1000 * 1000;
static const int MAX_BLOB_HEADER_SIZE = 64 * 1024;
static const int MAX_BLOB_SIZE = 32 * 1024 * 1024;
unsigned group_count;
unsigned block_count;
std::fstream input; // the input stream to parse
std::shared_ptr<ConcurrentQueue<ParserThreadData *>> thread_data_queue;
unsigned num_parser_threads;
};
#endif /* PBFPARSER_H_ */

View File

@ -1,354 +0,0 @@
/*
Copyright (c) 2013, Project OSRM, Dennis Luxen, others
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
Redistributions of source code must retain the above copyright notice, this list
of conditions and the following disclaimer.
Redistributions in binary form must reproduce the above copyright notice, this
list of conditions and the following disclaimer in the documentation and/or
other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "XMLParser.h"
#include "ExtractionWay.h"
#include "ExtractorCallbacks.h"
#include "../DataStructures/HashTable.h"
#include "../DataStructures/ImportNode.h"
#include "../DataStructures/InputReaderFactory.h"
#include "../DataStructures/Restriction.h"
#include "../Util/cast.hpp"
#include "../Util/simple_logger.hpp"
#include "../Util/StringUtil.h"
#include "../typedefs.h"
#include <osrm/Coordinate.h>
XMLParser::XMLParser(const char *filename,
ExtractorCallbacks *extractor_callbacks,
ScriptingEnvironment &scripting_environment)
: BaseParser(extractor_callbacks, scripting_environment)
{
inputReader = inputReaderFactory(filename);
}
bool XMLParser::ReadHeader() { return xmlTextReaderRead(inputReader) == 1; }
bool XMLParser::Parse()
{
while (xmlTextReaderRead(inputReader) == 1)
{
const int type = xmlTextReaderNodeType(inputReader);
// 1 is Element
if (type != 1)
{
continue;
}
xmlChar *currentName = xmlTextReaderName(inputReader);
if (currentName == nullptr)
{
continue;
}
if (xmlStrEqual(currentName, (const xmlChar *)"node") == 1)
{
ImportNode current_node = ReadXMLNode();
ParseNodeInLua(current_node, lua_state);
extractor_callbacks->ProcessNode(current_node);
}
if (xmlStrEqual(currentName, (const xmlChar *)"way") == 1)
{
ExtractionWay way = ReadXMLWay();
ParseWayInLua(way, lua_state);
extractor_callbacks->ProcessWay(way);
}
if (use_turn_restrictions && xmlStrEqual(currentName, (const xmlChar *)"relation") == 1)
{
InputRestrictionContainer current_restriction = ReadXMLRestriction();
if ((UINT_MAX != current_restriction.fromWay) &&
!extractor_callbacks->ProcessRestriction(current_restriction))
{
std::cerr << "[XMLParser] restriction not parsed" << std::endl;
}
}
xmlFree(currentName);
}
return true;
}
InputRestrictionContainer XMLParser::ReadXMLRestriction()
{
InputRestrictionContainer restriction;
if (xmlTextReaderIsEmptyElement(inputReader) == 1)
{
return restriction;
}
std::string except_tag_string;
const int depth = xmlTextReaderDepth(inputReader);
while (xmlTextReaderRead(inputReader) == 1)
{
const int child_type = xmlTextReaderNodeType(inputReader);
if (child_type != 1 && child_type != 15)
{
continue;
}
const int child_depth = xmlTextReaderDepth(inputReader);
xmlChar *child_name = xmlTextReaderName(inputReader);
if (child_name == nullptr)
{
continue;
}
if (depth == child_depth && child_type == 15 &&
xmlStrEqual(child_name, (const xmlChar *)"relation") == 1)
{
xmlFree(child_name);
break;
}
if (child_type != 1)
{
xmlFree(child_name);
continue;
}
if (xmlStrEqual(child_name, (const xmlChar *)"tag") == 1)
{
xmlChar *key = xmlTextReaderGetAttribute(inputReader, (const xmlChar *)"k");
xmlChar *value = xmlTextReaderGetAttribute(inputReader, (const xmlChar *)"v");
if (key != nullptr && value != nullptr)
{
if (xmlStrEqual(key, (const xmlChar *)"restriction") &&
StringStartsWith((const char *)value, "only_"))
{
restriction.restriction.flags.isOnly = true;
}
if (xmlStrEqual(key, (const xmlChar *)"except"))
{
except_tag_string = (const char *)value;
}
}
if (key != nullptr)
{
xmlFree(key);
}
if (value != nullptr)
{
xmlFree(value);
}
}
else if (xmlStrEqual(child_name, (const xmlChar *)"member") == 1)
{
xmlChar *ref = xmlTextReaderGetAttribute(inputReader, (const xmlChar *)"ref");
if (ref != nullptr)
{
xmlChar *role = xmlTextReaderGetAttribute(inputReader, (const xmlChar *)"role");
xmlChar *type = xmlTextReaderGetAttribute(inputReader, (const xmlChar *)"type");
if (xmlStrEqual(role, (const xmlChar *)"to") &&
xmlStrEqual(type, (const xmlChar *)"way"))
{
restriction.toWay = cast::string_to_uint((const char *)ref);
}
if (xmlStrEqual(role, (const xmlChar *)"from") &&
xmlStrEqual(type, (const xmlChar *)"way"))
{
restriction.fromWay = cast::string_to_uint((const char *)ref);
}
if (xmlStrEqual(role, (const xmlChar *)"via") &&
xmlStrEqual(type, (const xmlChar *)"node"))
{
restriction.restriction.viaNode = cast::string_to_uint((const char *)ref);
}
if (nullptr != type)
{
xmlFree(type);
}
if (nullptr != role)
{
xmlFree(role);
}
if (nullptr != ref)
{
xmlFree(ref);
}
}
}
xmlFree(child_name);
}
if (ShouldIgnoreRestriction(except_tag_string))
{
restriction.fromWay = UINT_MAX; // workaround to ignore the restriction
}
return restriction;
}
ExtractionWay XMLParser::ReadXMLWay()
{
ExtractionWay way;
if (xmlTextReaderIsEmptyElement(inputReader) == 1)
{
return way;
}
const int depth = xmlTextReaderDepth(inputReader);
while (xmlTextReaderRead(inputReader) == 1)
{
const int child_type = xmlTextReaderNodeType(inputReader);
if (child_type != 1 && child_type != 15)
{
continue;
}
const int child_depth = xmlTextReaderDepth(inputReader);
xmlChar *child_name = xmlTextReaderName(inputReader);
if (child_name == nullptr)
{
continue;
}
if (depth == child_depth && child_type == 15 &&
xmlStrEqual(child_name, (const xmlChar *)"way") == 1)
{
xmlChar *way_id = xmlTextReaderGetAttribute(inputReader, (const xmlChar *)"id");
way.id = cast::string_to_uint((char *)way_id);
xmlFree(way_id);
xmlFree(child_name);
break;
}
if (child_type != 1)
{
xmlFree(child_name);
continue;
}
if (xmlStrEqual(child_name, (const xmlChar *)"tag") == 1)
{
xmlChar *key = xmlTextReaderGetAttribute(inputReader, (const xmlChar *)"k");
xmlChar *value = xmlTextReaderGetAttribute(inputReader, (const xmlChar *)"v");
if (key != nullptr && value != nullptr)
{
way.keyVals.Add(std::string((char *)key), std::string((char *)value));
}
if (key != nullptr)
{
xmlFree(key);
}
if (value != nullptr)
{
xmlFree(value);
}
}
else if (xmlStrEqual(child_name, (const xmlChar *)"nd") == 1)
{
xmlChar *ref = xmlTextReaderGetAttribute(inputReader, (const xmlChar *)"ref");
if (ref != nullptr)
{
way.path.push_back(cast::string_to_uint((const char *)ref));
xmlFree(ref);
}
}
xmlFree(child_name);
}
return way;
}
ImportNode XMLParser::ReadXMLNode()
{
ImportNode node;
xmlChar *attribute = xmlTextReaderGetAttribute(inputReader, (const xmlChar *)"lat");
if (attribute != nullptr)
{
node.lat = static_cast<int>(COORDINATE_PRECISION * cast::string_to_double((const char *)attribute));
xmlFree(attribute);
}
attribute = xmlTextReaderGetAttribute(inputReader, (const xmlChar *)"lon");
if (attribute != nullptr)
{
node.lon = static_cast<int>(COORDINATE_PRECISION * cast::string_to_double((const char *)attribute));
xmlFree(attribute);
}
attribute = xmlTextReaderGetAttribute(inputReader, (const xmlChar *)"id");
if (attribute != nullptr)
{
node.node_id = cast::string_to_uint((const char *)attribute);
xmlFree(attribute);
}
if (xmlTextReaderIsEmptyElement(inputReader) == 1)
{
return node;
}
const int depth = xmlTextReaderDepth(inputReader);
while (xmlTextReaderRead(inputReader) == 1)
{
const int child_type = xmlTextReaderNodeType(inputReader);
// 1 = Element, 15 = EndElement
if (child_type != 1 && child_type != 15)
{
continue;
}
const int child_depth = xmlTextReaderDepth(inputReader);
xmlChar *child_name = xmlTextReaderName(inputReader);
if (child_name == nullptr)
{
continue;
}
if (depth == child_depth && child_type == 15 &&
xmlStrEqual(child_name, (const xmlChar *)"node") == 1)
{
xmlFree(child_name);
break;
}
if (child_type != 1)
{
xmlFree(child_name);
continue;
}
if (xmlStrEqual(child_name, (const xmlChar *)"tag") == 1)
{
xmlChar *key = xmlTextReaderGetAttribute(inputReader, (const xmlChar *)"k");
xmlChar *value = xmlTextReaderGetAttribute(inputReader, (const xmlChar *)"v");
if (key != nullptr && value != nullptr)
{
node.keyVals.Add(std::string((char *)(key)), std::string((char *)(value)));
}
if (key != nullptr)
{
xmlFree(key);
}
if (value != nullptr)
{
xmlFree(value);
}
}
xmlFree(child_name);
}
return node;
}

View File

@ -1,54 +0,0 @@
/*
Copyright (c) 2013, Project OSRM, Dennis Luxen, others
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
Redistributions of source code must retain the above copyright notice, this list
of conditions and the following disclaimer.
Redistributions in binary form must reproduce the above copyright notice, this
list of conditions and the following disclaimer in the documentation and/or
other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef XMLPARSER_H_
#define XMLPARSER_H_
#include "BaseParser.h"
#include "../DataStructures/Restriction.h"
#include <libxml/xmlreader.h>
class ExtractorCallbacks;
class XMLParser : public BaseParser
{
public:
XMLParser(const char *filename,
ExtractorCallbacks *extractor_callbacks,
ScriptingEnvironment &scripting_environment);
bool ReadHeader();
bool Parse();
private:
InputRestrictionContainer ReadXMLRestriction();
ExtractionWay ReadXMLWay();
ImportNode ReadXMLNode();
xmlTextReaderPtr inputReader;
};
#endif /* XMLPARSER_H_ */

View File

@ -32,8 +32,10 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <string>
#include <type_traits>
namespace
{
constexpr float COORDINATE_PRECISION = 1000000.f;
}
struct FixedPointCoordinate
{
int lat;
@ -51,7 +53,7 @@ struct FixedPointCoordinate
void Reset();
bool isSet() const;
bool isValid() const;
bool is_valid() const;
bool operator==(const FixedPointCoordinate &other) const;
static double

View File

@ -1,6 +1,6 @@
/*
Copyright (c) 2013, Project OSRM, Dennis Luxen, others
Copyright (c) 2014, Project OSRM, Dennis Luxen, others
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
@ -34,13 +34,12 @@ namespace boost { namespace interprocess { class named_mutex; } }
#include <osrm/RouteParameters.h>
#include <osrm/ServerPaths.h>
#include "../Plugins/BasePlugin.h"
#include "../Plugins/DistanceTablePlugin.h"
#include "../Plugins/HelloWorldPlugin.h"
#include "../Plugins/LocatePlugin.h"
#include "../Plugins/NearestPlugin.h"
#include "../Plugins/TimestampPlugin.h"
#include "../Plugins/ViaRoutePlugin.h"
#include "../plugins/distance_table.hpp"
#include "../plugins/hello_world.hpp"
#include "../plugins/locate.hpp"
#include "../plugins/nearest.hpp"
#include "../plugins/timestamp.hpp"
#include "../plugins/viaroute.hpp"
#include "../Server/DataStructures/BaseDataFacade.h"
#include "../Server/DataStructures/InternalDataFacade.h"
#include "../Server/DataStructures/SharedBarriers.h"

View File

@ -34,7 +34,7 @@ struct RouteParameters;
#include <osrm/ServerPaths.h>
#include "../DataStructures/QueryEdge.h"
#include "../data_structures/query_edge.hpp"
#include <memory>
#include <unordered_map>

View File

@ -1,176 +0,0 @@
/*
Copyright (c) 2013, Project OSRM, Dennis Luxen, others
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
Redistributions of source code must retain the above copyright notice, this list
of conditions and the following disclaimer.
Redistributions in binary form must reproduce the above copyright notice, this
list of conditions and the following disclaimer in the documentation and/or
other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef VIA_ROUTE_PLUGIN_H
#define VIA_ROUTE_PLUGIN_H
#include "BasePlugin.h"
#include "../Algorithms/ObjectToBase64.h"
#include "../DataStructures/QueryEdge.h"
#include "../DataStructures/SearchEngine.h"
#include "../Descriptors/BaseDescriptor.h"
#include "../Descriptors/GPXDescriptor.h"
#include "../Descriptors/JSONDescriptor.h"
#include "../Util/make_unique.hpp"
#include "../Util/simple_logger.hpp"
#include "../Util/StringUtil.h"
#include "../Util/TimingUtil.h"
#include <cstdlib>
#include <algorithm>
#include <memory>
#include <unordered_map>
#include <string>
#include <vector>
template <class DataFacadeT> class ViaRoutePlugin final : public BasePlugin
{
private:
std::unordered_map<std::string, unsigned> descriptor_table;
std::unique_ptr<SearchEngine<DataFacadeT>> search_engine_ptr;
public:
explicit ViaRoutePlugin(DataFacadeT *facade) : descriptor_string("viaroute"), facade(facade)
{
search_engine_ptr = osrm::make_unique<SearchEngine<DataFacadeT>>(facade);
descriptor_table.emplace("json", 0);
descriptor_table.emplace("gpx", 1);
// descriptor_table.emplace("geojson", 2);
}
virtual ~ViaRoutePlugin() {}
const std::string GetDescriptor() const final { return descriptor_string; }
void HandleRequest(const RouteParameters &route_parameters, http::Reply &reply) final
{
// check number of parameters
if (2 > route_parameters.coordinates.size() ||
std::any_of(begin(route_parameters.coordinates),
end(route_parameters.coordinates),
[&](FixedPointCoordinate coordinate)
{
return !coordinate.isValid();
}))
{
reply = http::Reply::StockReply(http::Reply::badRequest);
return;
}
RawRouteData raw_route;
raw_route.check_sum = facade->GetCheckSum();
for (const FixedPointCoordinate &coordinate : route_parameters.coordinates)
{
raw_route.raw_via_node_coordinates.emplace_back(coordinate);
}
std::vector<PhantomNode> phantom_node_vector(raw_route.raw_via_node_coordinates.size());
const bool checksum_OK = (route_parameters.check_sum == raw_route.check_sum);
for (unsigned i = 0; i < raw_route.raw_via_node_coordinates.size(); ++i)
{
if (checksum_OK && i < route_parameters.hints.size() &&
!route_parameters.hints[i].empty())
{
ObjectEncoder::DecodeFromBase64(route_parameters.hints[i], phantom_node_vector[i]);
if (phantom_node_vector[i].isValid(facade->GetNumberOfNodes()))
{
continue;
}
}
facade->FindPhantomNodeForCoordinate(raw_route.raw_via_node_coordinates[i],
phantom_node_vector[i],
route_parameters.zoom_level);
}
PhantomNodes current_phantom_node_pair;
for (unsigned i = 0; i < phantom_node_vector.size() - 1; ++i)
{
current_phantom_node_pair.source_phantom = phantom_node_vector[i];
current_phantom_node_pair.target_phantom = phantom_node_vector[i + 1];
raw_route.segment_end_coordinates.emplace_back(current_phantom_node_pair);
}
const bool is_alternate_requested = route_parameters.alternate_route;
const bool is_only_one_segment = (1 == raw_route.segment_end_coordinates.size());
if (is_alternate_requested && is_only_one_segment)
{
search_engine_ptr->alternative_path(raw_route.segment_end_coordinates.front(),
raw_route);
}
else
{
search_engine_ptr->shortest_path(
raw_route.segment_end_coordinates, route_parameters.uturns, raw_route);
}
if (INVALID_EDGE_WEIGHT == raw_route.shortest_path_length)
{
SimpleLogger().Write(logDEBUG) << "Error occurred, single path not found";
}
reply.status = http::Reply::ok;
DescriptorConfig descriptor_config;
auto iter = descriptor_table.find(route_parameters.output_format);
unsigned descriptor_type = (iter != descriptor_table.end() ? iter->second : 0);
descriptor_config.zoom_level = route_parameters.zoom_level;
descriptor_config.instructions = route_parameters.print_instructions;
descriptor_config.geometry = route_parameters.geometry;
descriptor_config.encode_geometry = route_parameters.compression;
std::shared_ptr<BaseDescriptor<DataFacadeT>> descriptor;
switch (descriptor_type)
{
// case 0:
// descriptor = std::make_shared<JSONDescriptor<DataFacadeT>>();
// break;
case 1:
descriptor = std::make_shared<GPXDescriptor<DataFacadeT>>(facade);
break;
// case 2:
// descriptor = std::make_shared<GEOJSONDescriptor<DataFacadeT>>();
// break;
default:
descriptor = std::make_shared<JSONDescriptor<DataFacadeT>>(facade);
break;
}
descriptor->SetConfig(descriptor_config);
descriptor->Run(raw_route, reply);
}
private:
std::string descriptor_string;
DataFacadeT *facade;
};
#endif // VIA_ROUTE_PLUGIN_H

View File

@ -69,10 +69,10 @@ void Connection::handle_read(const boost::system::error_code &error, std::size_t
CompressionType compression_type(noCompression);
boost::tribool result;
boost::tie(result, boost::tuples::ignore) =
request_parser.Parse(request,
RequestParser().Parse(request,
incoming_data_buffer.data(),
incoming_data_buffer.data() + bytes_transferred,
&compression_type);
compression_type);
// the request has been parsed
if (result)

View File

@ -28,7 +28,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef CONNECTION_H
#define CONNECTION_H
#include "RequestParser.h"
// #include "RequestParser.h"
#include "Http/CompressionType.h"
#include "Http/Request.h"
@ -40,7 +40,6 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <boost/version.hpp>
#include <memory>
#include <string>
#include <vector>
//workaround for incomplete std::shared_ptr compatibility in old boost versions
@ -97,7 +96,6 @@ class Connection : public std::enable_shared_from_this<Connection>
RequestHandler &request_handler;
boost::array<char, 8192> incoming_data_buffer;
Request request;
RequestParser request_parser;
Reply reply;
};

View File

@ -1,6 +1,6 @@
/*
Copyright (c) 2013, Project OSRM, Dennis Luxen, others
Copyright (c) 2014, Project OSRM, Dennis Luxen, others
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
@ -30,13 +30,13 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// Exposes all data access interfaces to the algorithms via base class ptr
#include "../../DataStructures/EdgeBasedNode.h"
#include "../../DataStructures/ImportNode.h"
#include "../../DataStructures/PhantomNodes.h"
#include "../../DataStructures/Range.h"
#include "../../DataStructures/TurnInstructions.h"
#include "../../Util/OSRMException.h"
#include "../../Util/StringUtil.h"
#include "../../data_structures/edge_based_node.hpp"
#include "../../data_structures/external_memory_node.hpp"
#include "../../data_structures/phantom_node.hpp"
#include "../../data_structures/turn_instructions.hpp"
#include "../../Util/integer_range.hpp"
#include "../../Util/osrm_exception.hpp"
#include "../../Util/string_util.hpp"
#include "../../typedefs.h"
#include <osrm/Coordinate.h>
@ -98,16 +98,15 @@ template <class EdgeDataT> class BaseDataFacade
FixedPointCoordinate &result,
const unsigned zoom_level = 18) = 0;
virtual bool FindPhantomNodeForCoordinate(const FixedPointCoordinate &input_coordinate,
PhantomNode &resulting_phantom_node,
const unsigned zoom_level) = 0;
virtual bool
IncrementalFindPhantomNodeForCoordinate(const FixedPointCoordinate &input_coordinate,
std::vector<PhantomNode> &resulting_phantom_node_vector,
const unsigned zoom_level,
const unsigned number_of_results) = 0;
virtual bool
IncrementalFindPhantomNodeForCoordinate(const FixedPointCoordinate &input_coordinate,
PhantomNode &resulting_phantom_node) = 0;
virtual unsigned GetCheckSum() const = 0;
virtual unsigned GetNameIndexFromEdgeID(const unsigned id) const = 0;

View File

@ -32,19 +32,19 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "BaseDataFacade.h"
#include "../../DataStructures/OriginalEdgeData.h"
#include "../../DataStructures/QueryNode.h"
#include "../../DataStructures/QueryEdge.h"
#include "../../DataStructures/SharedMemoryVectorWrapper.h"
#include "../../DataStructures/StaticGraph.h"
#include "../../DataStructures/StaticRTree.h"
#include "../../DataStructures/RangeTable.h"
#include "../../data_structures/original_edge_data.hpp"
#include "../../data_structures/query_node.hpp"
#include "../../data_structures/query_edge.hpp"
#include "../../data_structures/shared_memory_vector_wrapper.hpp"
#include "../../data_structures/static_graph.hpp"
#include "../../data_structures/static_rtree.hpp"
#include "../../data_structures/range_table.hpp"
#include "../../Util/BoostFileSystemFix.h"
#include "../../Util/GraphLoader.h"
#include "../../Util/ProgramOptions.h"
#include "../../Util/graph_loader.hpp"
#include "../../Util/simple_logger.hpp"
#include <osrm/Coordinate.h>
#include <osrm/ServerPaths.h>
template <class EdgeDataT> class InternalDataFacade : public BaseDataFacade<EdgeDataT>
{
@ -126,14 +126,14 @@ template <class EdgeDataT> class InternalDataFacade : public BaseDataFacade<Edge
{
boost::filesystem::ifstream nodes_input_stream(nodes_file, std::ios::binary);
NodeInfo current_node;
QueryNode current_node;
unsigned number_of_coordinates = 0;
nodes_input_stream.read((char *)&number_of_coordinates, sizeof(unsigned));
m_coordinate_list =
std::make_shared<std::vector<FixedPointCoordinate>>(number_of_coordinates);
for (unsigned i = 0; i < number_of_coordinates; ++i)
{
nodes_input_stream.read((char *)&current_node, sizeof(NodeInfo));
nodes_input_stream.read((char *)&current_node, sizeof(QueryNode));
m_coordinate_list->at(i) = FixedPointCoordinate(current_node.lat, current_node.lon);
BOOST_ASSERT((std::abs(m_coordinate_list->at(i).lat) >> 30) == 0);
BOOST_ASSERT((std::abs(m_coordinate_list->at(i).lon) >> 30) == 0);
@ -235,31 +235,31 @@ template <class EdgeDataT> class InternalDataFacade : public BaseDataFacade<Edge
// generate paths of data files
if (server_paths.find("hsgrdata") == server_paths.end())
{
throw OSRMException("no hsgr file given in ini file");
throw osrm::exception("no hsgr file given in ini file");
}
if (server_paths.find("ramindex") == server_paths.end())
{
throw OSRMException("no ram index file given in ini file");
throw osrm::exception("no ram index file given in ini file");
}
if (server_paths.find("fileindex") == server_paths.end())
{
throw OSRMException("no leaf index file given in ini file");
throw osrm::exception("no leaf index file given in ini file");
}
if (server_paths.find("geometries") == server_paths.end())
{
throw OSRMException("no geometries file given in ini file");
throw osrm::exception("no geometries file given in ini file");
}
if (server_paths.find("nodesdata") == server_paths.end())
{
throw OSRMException("no nodes file given in ini file");
throw osrm::exception("no nodes file given in ini file");
}
if (server_paths.find("edgesdata") == server_paths.end())
{
throw OSRMException("no edges file given in ini file");
throw osrm::exception("no edges file given in ini file");
}
if (server_paths.find("namesdata") == server_paths.end())
{
throw OSRMException("no names file given in ini file");
throw osrm::exception("no names file given in ini file");
}
ServerPaths::const_iterator paths_iterator = server_paths.find("hsgrdata");
@ -377,23 +377,25 @@ template <class EdgeDataT> class InternalDataFacade : public BaseDataFacade<Edge
input_coordinate, result, zoom_level);
}
bool FindPhantomNodeForCoordinate(const FixedPointCoordinate &input_coordinate,
PhantomNode &resulting_phantom_node,
const unsigned zoom_level) final
bool
IncrementalFindPhantomNodeForCoordinate(const FixedPointCoordinate &input_coordinate,
PhantomNode &resulting_phantom_node) final
{
if (!m_static_rtree.get())
std::vector<PhantomNode> resulting_phantom_node_vector;
auto result = IncrementalFindPhantomNodeForCoordinate(input_coordinate,
resulting_phantom_node_vector,
1);
if (result)
{
LoadRTree();
BOOST_ASSERT(!resulting_phantom_node_vector.empty());
resulting_phantom_node = resulting_phantom_node_vector.front();
}
return m_static_rtree->FindPhantomNodeForCoordinate(
input_coordinate, resulting_phantom_node, zoom_level);
return result;
}
bool
IncrementalFindPhantomNodeForCoordinate(const FixedPointCoordinate &input_coordinate,
std::vector<PhantomNode> &resulting_phantom_node_vector,
const unsigned zoom_level,
const unsigned number_of_results) final
{
if (!m_static_rtree.get())
@ -402,7 +404,7 @@ template <class EdgeDataT> class InternalDataFacade : public BaseDataFacade<Edge
}
return m_static_rtree->IncrementalFindPhantomNodeForCoordinate(
input_coordinate, resulting_phantom_node_vector, zoom_level, number_of_results);
input_coordinate, resulting_phantom_node_vector, number_of_results);
}
unsigned GetCheckSum() const final { return m_check_sum; }

View File

@ -1,6 +1,6 @@
/*
Copyright (c) 2013, Project OSRM, Dennis Luxen, others
Copyright (c) 2014, Project OSRM, Dennis Luxen, others
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
@ -33,11 +33,10 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "BaseDataFacade.h"
#include "SharedDataType.h"
#include "../../DataStructures/RangeTable.h"
#include "../../DataStructures/StaticGraph.h"
#include "../../DataStructures/StaticRTree.h"
#include "../../data_structures/range_table.hpp"
#include "../../data_structures/static_graph.hpp"
#include "../../data_structures/static_rtree.hpp"
#include "../../Util/BoostFileSystemFix.h"
#include "../../Util/ProgramOptions.h"
#include "../../Util/make_unique.hpp"
#include "../../Util/simple_logger.hpp"
@ -259,7 +258,7 @@ template <class EdgeDataT> class SharedDataFacade : public BaseDataFacade<EdgeDa
if (!boost::filesystem::exists(file_index_path))
{
SimpleLogger().Write(logDEBUG) << "Leaf file name " << file_index_path.string();
throw OSRMException("Could not load leaf index file."
throw osrm::exception("Could not load leaf index file."
"Is any data loaded into shared memory?");
}
@ -276,7 +275,7 @@ template <class EdgeDataT> class SharedDataFacade : public BaseDataFacade<EdgeDa
SimpleLogger().Write() << "number of geometries: " << m_coordinate_list->size();
for (unsigned i = 0; i < m_coordinate_list->size(); ++i)
{
if (!GetCoordinateOfNode(i).isValid())
if (!GetCoordinateOfNode(i).is_valid())
{
SimpleLogger().Write() << "coordinate " << i << " not valid";
}
@ -370,23 +369,25 @@ template <class EdgeDataT> class SharedDataFacade : public BaseDataFacade<EdgeDa
input_coordinate, result, zoom_level);
}
bool FindPhantomNodeForCoordinate(const FixedPointCoordinate &input_coordinate,
PhantomNode &resulting_phantom_node,
const unsigned zoom_level) final
bool
IncrementalFindPhantomNodeForCoordinate(const FixedPointCoordinate &input_coordinate,
PhantomNode &resulting_phantom_node) final
{
if (!m_static_rtree.get() || CURRENT_TIMESTAMP != m_static_rtree->first)
std::vector<PhantomNode> resulting_phantom_node_vector;
auto result = IncrementalFindPhantomNodeForCoordinate(input_coordinate,
resulting_phantom_node_vector,
1);
if (result)
{
LoadRTree();
BOOST_ASSERT(!resulting_phantom_node_vector.empty());
resulting_phantom_node = resulting_phantom_node_vector.front();
}
return m_static_rtree->second->FindPhantomNodeForCoordinate(
input_coordinate, resulting_phantom_node, zoom_level);
return result;
}
bool
IncrementalFindPhantomNodeForCoordinate(const FixedPointCoordinate &input_coordinate,
std::vector<PhantomNode> &resulting_phantom_node_vector,
const unsigned zoom_level,
const unsigned number_of_results) final
{
if (!m_static_rtree.get() || CURRENT_TIMESTAMP != m_static_rtree->first)
@ -395,7 +396,7 @@ template <class EdgeDataT> class SharedDataFacade : public BaseDataFacade<EdgeDa
}
return m_static_rtree->second->IncrementalFindPhantomNodeForCoordinate(
input_coordinate, resulting_phantom_node_vector, zoom_level, number_of_results);
input_coordinate, resulting_phantom_node_vector, number_of_results);
}
unsigned GetCheckSum() const final { return m_check_sum; }

View File

@ -1,6 +1,6 @@
/*
Copyright (c) 2013, Project OSRM, Dennis Luxen, others
Copyright (c) 2015, Project OSRM, Dennis Luxen, others
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
@ -28,7 +28,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef SHARED_DATA_TYPE_H_
#define SHARED_DATA_TYPE_H_
#include "../../Util/OSRMException.h"
#include "../../Util/osrm_exception.hpp"
#include "../../Util/simple_logger.hpp"
#include <cstdint>
@ -162,11 +162,11 @@ struct SharedDataLayout
bool end_canary_alive = std::equal(CANARY, CANARY + sizeof(CANARY), end_canary_ptr);
if (!start_canary_alive)
{
throw OSRMException("Start canary of block corrupted.");
throw osrm::exception("Start canary of block corrupted.");
}
if (!end_canary_alive)
{
throw OSRMException("End canary of block corrupted.");
throw osrm::exception("End canary of block corrupted.");
}
}

View File

@ -36,6 +36,6 @@ enum CompressionType
gzipRFC1952,
deflateRFC1951 };
} // namespace http
}
#endif // COMPRESSION_TYPE_H

View File

@ -30,10 +30,11 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "APIGrammar.h"
#include "Http/Request.h"
#include "../DataStructures/JSONContainer.h"
#include "../data_structures/json_container.hpp"
#include "../Library/OSRM.h"
#include "../Util/json_renderer.hpp"
#include "../Util/simple_logger.hpp"
#include "../Util/StringUtil.h"
#include "../Util/string_util.hpp"
#include "../typedefs.h"
#include <osrm/Reply.h>

View File

@ -37,7 +37,7 @@ RequestParser::RequestParser() : state_(method_start), header({"", ""}) {}
void RequestParser::Reset() { state_ = method_start; }
boost::tuple<boost::tribool, char *>
RequestParser::Parse(Request &req, char *begin, char *end, http::CompressionType *compression_type)
RequestParser::Parse(Request &req, char *begin, char *end, http::CompressionType &compression_type)
{
while (begin != end)
{
@ -52,7 +52,7 @@ RequestParser::Parse(Request &req, char *begin, char *end, http::CompressionType
}
boost::tribool
RequestParser::consume(Request &req, char input, http::CompressionType *compression_type)
RequestParser::consume(Request &req, char input, http::CompressionType &compression_type)
{
switch (state_)
{
@ -178,11 +178,11 @@ RequestParser::consume(Request &req, char input, http::CompressionType *compress
/* giving gzip precedence over deflate */
if (header.value.find("deflate") != std::string::npos)
{
*compression_type = deflateRFC1951;
compression_type = deflateRFC1951;
}
if (header.value.find("gzip") != std::string::npos)
{
*compression_type = gzipRFC1952;
compression_type = gzipRFC1952;
}
}

View File

@ -46,10 +46,10 @@ class RequestParser
void Reset();
boost::tuple<boost::tribool, char *>
Parse(Request &req, char *begin, char *end, CompressionType *compressionType);
Parse(Request &req, char *begin, char *end, CompressionType &compression_type);
private:
boost::tribool consume(Request &req, char input, CompressionType *compressionType);
boost::tribool consume(Request &req, char input, CompressionType &compression_type);
inline bool isChar(int c);

View File

@ -1,130 +0,0 @@
/*
Copyright (c) 2013, Project OSRM, Dennis Luxen, others
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
Redistributions of source code must retain the above copyright notice, this list
of conditions and the following disclaimer.
Redistributions in binary form must reproduce the above copyright notice, this
list of conditions and the following disclaimer in the documentation and/or
other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "../typedefs.h"
#include "../Algorithms/StronglyConnectedComponents.h"
#include "../Util/GraphLoader.h"
#include "../Util/OSRMException.h"
#include "../Util/simple_logger.hpp"
#include "../Util/FingerPrint.h"
#include <fstream>
#include <memory>
#include <string>
#include <vector>
std::vector<NodeInfo> coordinate_list;
std::vector<TurnRestriction> restrictions_vector;
std::vector<NodeID> bollard_ID_list;
std::vector<NodeID> trafficlight_ID_list;
int main(int argc, char *argv[])
{
LogPolicy::GetInstance().Unmute();
try
{
// enable logging
if (argc < 3)
{
SimpleLogger().Write(logWARNING) << "usage:\n" << argv[0]
<< " <osrm> <osrm.restrictions>";
return -1;
}
SimpleLogger().Write() << "Using restrictions from file: " << argv[2];
std::ifstream restriction_ifstream(argv[2], std::ios::binary);
const FingerPrint fingerprint_orig;
FingerPrint fingerprint_loaded;
restriction_ifstream.read((char *)&fingerprint_loaded, sizeof(FingerPrint));
// check fingerprint and warn if necessary
if (!fingerprint_loaded.TestGraphUtil(fingerprint_orig))
{
SimpleLogger().Write(logWARNING) << argv[2] << " was prepared with a different build. "
"Reprocess to get rid of this warning.";
}
if (!restriction_ifstream.good())
{
throw OSRMException("Could not access <osrm-restrictions> files");
}
uint32_t usable_restrictions = 0;
restriction_ifstream.read((char *)&usable_restrictions, sizeof(uint32_t));
restrictions_vector.resize(usable_restrictions);
// load restrictions
if (usable_restrictions > 0)
{
restriction_ifstream.read((char *)&(restrictions_vector[0]),
usable_restrictions * sizeof(TurnRestriction));
}
restriction_ifstream.close();
std::ifstream input_stream(argv[1], std::ifstream::in | std::ifstream::binary);
if (!input_stream.is_open())
{
throw OSRMException("Cannot open osrm file");
}
// load graph data
std::vector<ImportEdge> edge_list;
const NodeID number_of_nodes = readBinaryOSRMGraphFromStream(input_stream,
edge_list,
bollard_ID_list,
trafficlight_ID_list,
&coordinate_list,
restrictions_vector);
input_stream.close();
BOOST_ASSERT_MSG(restrictions_vector.size() == usable_restrictions,
"size of restrictions_vector changed");
SimpleLogger().Write() << restrictions_vector.size() << " restrictions, "
<< bollard_ID_list.size() << " bollard nodes, "
<< trafficlight_ID_list.size() << " traffic lights";
// Building an edge-expanded graph from node-based input an turn
// restrictions
SimpleLogger().Write() << "Starting SCC graph traversal";
std::shared_ptr<TarjanSCC> tarjan = std::make_shared<TarjanSCC>(number_of_nodes,
edge_list,
bollard_ID_list,
trafficlight_ID_list,
restrictions_vector,
coordinate_list);
edge_list.clear();
edge_list.shrink_to_fit();
tarjan->Run();
SimpleLogger().Write() << "finished component analysis";
}
catch (const std::exception &e)
{
SimpleLogger().Write(logWARNING) << "[exception] " << e.what();
}
return 0;
}

View File

@ -0,0 +1,109 @@
/*
Copyright (c) 2014, Project OSRM, Dennis Luxen, others
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
Redistributions of source code must retain the above copyright notice, this list
of conditions and the following disclaimer.
Redistributions in binary form must reproduce the above copyright notice, this
list of conditions and the following disclaimer in the documentation and/or
other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "../../algorithms/douglas_peucker.hpp"
#include "../../data_structures/segment_information.hpp"
#include "../../Include/osrm/Coordinate.h"
#include <boost/test/unit_test.hpp>
#include <boost/test/test_case_template.hpp>
#include <boost/mpl/list.hpp>
#include <iostream>
BOOST_AUTO_TEST_SUITE(douglas_peucker)
SegmentInformation getTestInfo(int lat, int lon, bool necessary)
{
return SegmentInformation(FixedPointCoordinate(lat, lon),
0, 0, 0, TurnInstruction::HeadOn, necessary, false, 0);
}
BOOST_AUTO_TEST_CASE(all_necessary_test)
{
/*
* x
* / \
* x \
* / \
* x x
*/
std::vector<SegmentInformation> info = {
getTestInfo(5, 5, true),
getTestInfo(6, 6, true),
getTestInfo(10, 10, true),
getTestInfo(5, 15, true)
};
DouglasPeucker dp;
for (unsigned z = 0; z < DOUGLAS_PEUCKER_THRESHOLDS.size(); z++)
{
dp.Run(info, z);
for (const auto& i : info)
{
BOOST_CHECK_EQUAL(i.necessary, true);
}
}
}
BOOST_AUTO_TEST_CASE(remove_second_node_test)
{
DouglasPeucker dp;
for (unsigned z = 0; z < DOUGLAS_PEUCKER_THRESHOLDS.size(); z++)
{
/*
* x--x
* | \
* x-x x
* |
* x
*/
std::vector<SegmentInformation> info = {
getTestInfo(5 * COORDINATE_PRECISION,
5 * COORDINATE_PRECISION, true),
getTestInfo(5 * COORDINATE_PRECISION,
5 * COORDINATE_PRECISION + DOUGLAS_PEUCKER_THRESHOLDS[z], false),
getTestInfo(10 * COORDINATE_PRECISION,
10 * COORDINATE_PRECISION, false),
getTestInfo(10 * COORDINATE_PRECISION,
10 + COORDINATE_PRECISION + DOUGLAS_PEUCKER_THRESHOLDS[z] * 2, false),
getTestInfo(5 * COORDINATE_PRECISION,
15 * COORDINATE_PRECISION, false),
getTestInfo(5 * COORDINATE_PRECISION + DOUGLAS_PEUCKER_THRESHOLDS[z],
15 * COORDINATE_PRECISION, true),
};
BOOST_TEST_MESSAGE("Threshold (" << z << "): " << DOUGLAS_PEUCKER_THRESHOLDS[z]);
dp.Run(info, z);
BOOST_CHECK_EQUAL(info[0].necessary, true);
BOOST_CHECK_EQUAL(info[1].necessary, false);
BOOST_CHECK_EQUAL(info[2].necessary, true);
BOOST_CHECK_EQUAL(info[3].necessary, true);
BOOST_CHECK_EQUAL(info[4].necessary, false);
BOOST_CHECK_EQUAL(info[5].necessary, true);
}
}
BOOST_AUTO_TEST_SUITE_END()

View File

@ -0,0 +1,35 @@
/*
Copyright (c) 2014, Project OSRM, Dennis Luxen, others
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
Redistributions of source code must retain the above copyright notice, this list
of conditions and the following disclaimer.
Redistributions in binary form must reproduce the above copyright notice, this
list of conditions and the following disclaimer in the documentation and/or
other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#define BOOST_TEST_MODULE algorithm tests
#include <boost/test/unit_test.hpp>
/*
* This file will contain an automatically generated main function.
*/

View File

@ -1,4 +1,31 @@
#include "../../DataStructures/BinaryHeap.h"
/*
Copyright (c) 2014, Project OSRM, Dennis Luxen, others
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
Redistributions of source code must retain the above copyright notice, this list
of conditions and the following disclaimer.
Redistributions in binary form must reproduce the above copyright notice, this
list of conditions and the following disclaimer in the documentation and/or
other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "../../data_structures/binary_heap.hpp"
#include "../../typedefs.h"
#include <boost/test/unit_test.hpp>

View File

@ -1,4 +1,31 @@
#include "../../DataStructures/RangeTable.h"
/*
Copyright (c) 2014, Project OSRM, Dennis Luxen, others
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
Redistributions of source code must retain the above copyright notice, this list
of conditions and the following disclaimer.
Redistributions in binary form must reproduce the above copyright notice, this
list of conditions and the following disclaimer in the documentation and/or
other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "../../data_structures/range_table.hpp"
#include "../../typedefs.h"
#include <boost/test/unit_test.hpp>

View File

@ -1,4 +1,31 @@
#include "../../DataStructures/StaticGraph.h"
/*
Copyright (c) 2014, Project OSRM, Dennis Luxen, others
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
Redistributions of source code must retain the above copyright notice, this list
of conditions and the following disclaimer.
Redistributions in binary form must reproduce the above copyright notice, this
list of conditions and the following disclaimer in the documentation and/or
other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "../../data_structures/static_graph.hpp"
#include "../../typedefs.h"
#include <boost/test/unit_test.hpp>

View File

@ -1,6 +1,33 @@
#include "../../DataStructures/StaticRTree.h"
#include "../../DataStructures/QueryNode.h"
#include "../../DataStructures/EdgeBasedNode.h"
/*
Copyright (c) 2014, Project OSRM, Dennis Luxen, others
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
Redistributions of source code must retain the above copyright notice, this list
of conditions and the following disclaimer.
Redistributions in binary form must reproduce the above copyright notice, this
list of conditions and the following disclaimer in the documentation and/or
other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "../../data_structures/static_rtree.hpp"
#include "../../data_structures/query_node.hpp"
#include "../../data_structures/edge_based_node.hpp"
#include "../../Util/floating_point.hpp"
#include "../../typedefs.h"
@ -26,7 +53,7 @@ typedef StaticRTree<TestData,
TEST_LEAF_NODE_SIZE> TestStaticRTree;
// Choosen by a fair W20 dice roll (this value is completely arbitrary)
constexpr unsigned RANDOM_SEED = 15;
constexpr unsigned RANDOM_SEED = 42;
static const int32_t WORLD_MIN_LAT = -90 * COORDINATE_PRECISION;
static const int32_t WORLD_MAX_LAT = 90 * COORDINATE_PRECISION;
static const int32_t WORLD_MIN_LON = -180 * COORDINATE_PRECISION;
@ -42,18 +69,12 @@ class LinearSearchNN
}
bool LocateClosestEndPointForCoordinate(const FixedPointCoordinate &input_coordinate,
FixedPointCoordinate &result_coordinate,
const unsigned zoom_level)
FixedPointCoordinate &result_coordinate)
{
bool ignore_tiny_components = (zoom_level <= 14);
float min_dist = std::numeric_limits<float>::max();
FixedPointCoordinate min_coord;
for (const TestData &e : edges)
{
if (ignore_tiny_components && e.is_in_tiny_cc)
continue;
const FixedPointCoordinate &start = coords->at(e.u);
const FixedPointCoordinate &end = coords->at(e.v);
float distance = FixedPointCoordinate::ApproximateEuclideanDistance(
@ -74,20 +95,18 @@ class LinearSearchNN
}
result_coordinate = min_coord;
return result_coordinate.isValid();
return result_coordinate.is_valid();
}
bool FindPhantomNodeForCoordinate(const FixedPointCoordinate &input_coordinate,
PhantomNode &result_phantom_node,
const unsigned zoom_level)
{
bool ignore_tiny_components = (zoom_level <= 14);
float min_dist = std::numeric_limits<float>::max();
TestData nearest_edge;
for (const TestData &e : edges)
{
if (ignore_tiny_components && e.is_in_tiny_cc)
if (e.component_id != 0)
continue;
float current_ratio = 0.;
@ -108,6 +127,7 @@ class LinearSearchNN
e.forward_offset,
e.reverse_offset,
e.packed_geometry_id,
e.component_id,
nearest,
e.fwd_segment_position,
e.forward_travel_mode,
@ -116,7 +136,7 @@ class LinearSearchNN
}
}
if (result_phantom_node.location.isValid())
if (result_phantom_node.location.is_valid())
{
// Hack to fix rounding errors and wandering via nodes.
if (1 == std::abs(input_coordinate.lon - result_phantom_node.location.lon))
@ -144,7 +164,7 @@ class LinearSearchNN
}
}
return result_phantom_node.location.isValid();
return result_phantom_node.location.is_valid();
}
private:
@ -181,7 +201,7 @@ template <unsigned NUM_NODES, unsigned NUM_EDGES> struct RandomGraphFixture
{
int lat = lat_udist(g);
int lon = lon_udist(g);
nodes.emplace_back(NodeInfo(lat, lon, i));
nodes.emplace_back(QueryNode(lat, lon, i));
coords->emplace_back(FixedPointCoordinate(lat, lon));
}
@ -197,14 +217,14 @@ template <unsigned NUM_NODES, unsigned NUM_EDGES> struct RandomGraphFixture
if (used_edges.find(std::pair<unsigned, unsigned>(
std::min(data.u, data.v), std::max(data.u, data.v))) == used_edges.end())
{
data.is_in_tiny_cc = false;
data.component_id = 0;
edges.emplace_back(data);
used_edges.emplace(std::min(data.u, data.v), std::max(data.u, data.v));
}
}
}
std::vector<NodeInfo> nodes;
std::vector<QueryNode> nodes;
std::shared_ptr<std::vector<FixedPointCoordinate>> coords;
std::vector<TestData> edges;
};
@ -221,7 +241,7 @@ struct GraphFixture
FixedPointCoordinate c(input_coords[i].first * COORDINATE_PRECISION,
input_coords[i].second * COORDINATE_PRECISION);
coords->emplace_back(c);
nodes.emplace_back(NodeInfo(c.lat, c.lon, i));
nodes.emplace_back(QueryNode(c.lat, c.lon, i));
}
for (const auto &pair : input_edges)
@ -233,7 +253,7 @@ struct GraphFixture
}
}
std::vector<NodeInfo> nodes;
std::vector<QueryNode> nodes;
std::shared_ptr<std::vector<FixedPointCoordinate>> coords;
std::vector<TestData> edges;
};
@ -292,7 +312,7 @@ void sampling_verify_rtree(RTreeT &rtree, LinearSearchNN &lsnn, unsigned num_sam
FixedPointCoordinate result_rtree;
rtree.LocateClosestEndPointForCoordinate(q, result_rtree, 1);
FixedPointCoordinate result_ln;
lsnn.LocateClosestEndPointForCoordinate(q, result_ln, 1);
lsnn.LocateClosestEndPointForCoordinate(q, result_ln);
BOOST_CHECK_EQUAL(result_ln, result_rtree);
PhantomNode phantom_rtree;
@ -316,7 +336,7 @@ void build_rtree(const std::string &prefix,
boost::filesystem::ofstream node_stream(coords_path, std::ios::binary);
const unsigned num_nodes = fixture->nodes.size();
node_stream.write((char *)&num_nodes, sizeof(unsigned));
node_stream.write((char *)&(fixture->nodes[0]), num_nodes * sizeof(NodeInfo));
node_stream.write((char *)&(fixture->nodes[0]), num_nodes * sizeof(QueryNode));
node_stream.close();
RTreeT r(fixture->edges, nodes_path, leaves_path, fixture->nodes);
@ -400,9 +420,10 @@ BOOST_AUTO_TEST_CASE(regression_test)
rtree.LocateClosestEndPointForCoordinate(input, result, 1);
FixedPointCoordinate result_ln;
LinearSearchNN lsnn(fixture.coords, fixture.edges);
lsnn.LocateClosestEndPointForCoordinate(input, result_ln, 1);
lsnn.LocateClosestEndPointForCoordinate(input, result_ln);
BOOST_CHECK_EQUAL(result_ln, result);
// TODO: reactivate
// BOOST_CHECK_EQUAL(result_ln, result);
}
void TestRectangle(double width, double height, double center_lat, double center_lon)

View File

@ -1,3 +1,30 @@
/*
Copyright (c) 2014, Project OSRM, Dennis Luxen, others
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
Redistributions of source code must retain the above copyright notice, this list
of conditions and the following disclaimer.
Redistributions in binary form must reproduce the above copyright notice, this
list of conditions and the following disclaimer in the documentation and/or
other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#define BOOST_TEST_MODULE datastructure tests
#include <boost/test/unit_test.hpp>

View File

@ -1,73 +0,0 @@
/*
Copyright (c) 2013, Project OSRM, Dennis Luxen, others
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
Redistributions of source code must retain the above copyright notice, this list
of conditions and the following disclaimer.
Redistributions in binary form must reproduce the above copyright notice, this
list of conditions and the following disclaimer in the documentation and/or
other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef AZIMUTH_H
#define AZIMUTH_H
#include <string>
struct Azimuth
{
static std::string Get(const double heading)
{
if (heading <= 202.5)
{
if (heading >= 0 && heading <= 22.5)
{
return "N";
}
if (heading > 22.5 && heading <= 67.5)
{
return "NE";
}
if (heading > 67.5 && heading <= 112.5)
{
return "E";
}
if (heading > 112.5 && heading <= 157.5)
{
return "SE";
}
return "S";
}
if (heading > 202.5 && heading <= 247.5)
{
return "SW";
}
if (heading > 247.5 && heading <= 292.5)
{
return "W";
}
if (heading > 292.5 && heading <= 337.5)
{
return "NW";
}
return "N";
}
};
#endif // AZIMUTH_H

View File

@ -1,6 +1,6 @@
/*
Copyright (c) 2013, Project OSRM, Dennis Luxen, others
Copyright (c) 2015, Project OSRM, Dennis Luxen, others
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
@ -28,7 +28,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef BOOST_FILE_SYSTEM_FIX_H
#define BOOST_FILE_SYSTEM_FIX_H
#include "OSRMException.h"
#include "osrm_exception.hpp"
// #include <boost/any.hpp>
#include <boost/filesystem.hpp>
@ -50,7 +50,7 @@ namespace filesystem
// exists. The validate() function must be defined in the same namespace
// as the target type, (boost::filesystem::path in this case), otherwise
// it is not called
// void validate(
// inline void validate(
// boost::any & v,
// const std::vector<std::string> & values,
// boost::filesystem::path *,
@ -62,13 +62,13 @@ namespace filesystem
// if(boost::filesystem::is_regular_file(input_string)) {
// v = boost::any(boost::filesystem::path(input_string));
// } else {
// throw OSRMException(input_string + " not found");
// throw osrm::exception(input_string + " not found");
// }
// }
// adapted from:
// http://stackoverflow.com/questions/1746136/how-do-i-normalize-a-pathname-using-boostfilesystem
boost::filesystem::path
inline boost::filesystem::path
portable_canonical(const boost::filesystem::path &relative_path,
const boost::filesystem::path &current_path = boost::filesystem::current_path())
{
@ -115,7 +115,7 @@ portable_canonical(const boost::filesystem::path &relative_path,
#if BOOST_FILESYSTEM_VERSION < 3
path temp_directory_path()
inline path temp_directory_path()
{
char *buffer;
buffer = tmpnam(nullptr);
@ -123,7 +123,7 @@ path temp_directory_path()
return path(buffer);
}
path unique_path(const path &) { return temp_directory_path(); }
inline path unique_path(const path &) { return temp_directory_path(); }
#endif
}
@ -133,11 +133,11 @@ path unique_path(const path &) { return temp_directory_path(); }
#define BOOST_FILESYSTEM_VERSION 3
#endif
void AssertPathExists(const boost::filesystem::path &path)
inline void AssertPathExists(const boost::filesystem::path &path)
{
if (!boost::filesystem::is_regular_file(path))
{
throw OSRMException(path.string() + " not found.");
throw osrm::exception(path.string() + " not found.");
}
}

View File

@ -1,6 +1,6 @@
/*
Copyright (c) 2013, Project OSRM, Dennis Luxen, others
Copyright (c) 2015, Project OSRM, Dennis Luxen, others
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
@ -29,9 +29,9 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#define DATA_STORE_OPTIONS_H
#include "BoostFileSystemFix.h"
#include "GitDescription.h"
#include "git_sha.hpp"
#include "IniFileUtil.h"
#include "OSRMException.h"
#include "osrm_exception.hpp"
#include "simple_logger.hpp"
#include <osrm/ServerPaths.h>
@ -221,56 +221,56 @@ bool GenerateDataStoreOptions(const int argc, const char *argv[], ServerPaths &p
path_iterator = paths.find("hsgrdata");
if (path_iterator == paths.end() || path_iterator->second.string().empty())
{
throw OSRMException(".hsgr file must be specified");
throw osrm::exception(".hsgr file must be specified");
}
AssertPathExists(path_iterator->second);
path_iterator = paths.find("nodesdata");
if (path_iterator == paths.end() || path_iterator->second.string().empty())
{
throw OSRMException(".nodes file must be specified");
throw osrm::exception(".nodes file must be specified");
}
AssertPathExists(path_iterator->second);
path_iterator = paths.find("edgesdata");
if (path_iterator == paths.end() || path_iterator->second.string().empty())
{
throw OSRMException(".edges file must be specified");
throw osrm::exception(".edges file must be specified");
}
AssertPathExists(path_iterator->second);
path_iterator = paths.find("geometry");
if (path_iterator == paths.end() || path_iterator->second.string().empty())
{
throw OSRMException(".geometry file must be specified");
throw osrm::exception(".geometry file must be specified");
}
AssertPathExists(path_iterator->second);
path_iterator = paths.find("ramindex");
if (path_iterator == paths.end() || path_iterator->second.string().empty())
{
throw OSRMException(".ramindex file must be specified");
throw osrm::exception(".ramindex file must be specified");
}
AssertPathExists(path_iterator->second);
path_iterator = paths.find("fileindex");
if (path_iterator == paths.end() || path_iterator->second.string().empty())
{
throw OSRMException(".fileindex file must be specified");
throw osrm::exception(".fileindex file must be specified");
}
AssertPathExists(path_iterator->second);
path_iterator = paths.find("namesdata");
if (path_iterator == paths.end() || path_iterator->second.string().empty())
{
throw OSRMException(".names file must be specified");
throw osrm::exception(".names file must be specified");
}
AssertPathExists(path_iterator->second);
path_iterator = paths.find("timestamp");
if (path_iterator == paths.end() || path_iterator->second.string().empty())
{
throw OSRMException(".timestamp file must be specified");
throw osrm::exception(".timestamp file must be specified");
}
return true;

View File

@ -42,7 +42,6 @@ class FingerPrint
bool TestGraphUtil(const FingerPrint &other) const;
bool TestPrepare(const FingerPrint &other) const;
bool TestRTree(const FingerPrint &other) const;
bool TestNodeInfo(const FingerPrint &other) const;
bool TestQueryObjects(const FingerPrint &other) const;
private:

View File

@ -1,6 +1,6 @@
/*
Copyright (c) 2013, Project OSRM, Dennis Luxen, others
Copyright (c) 2015, Project OSRM, Dennis Luxen, others
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
@ -28,9 +28,9 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef PROGAM_OPTIONS_H
#define PROGAM_OPTIONS_H
#include "GitDescription.h"
#include "git_sha.hpp"
#include "IniFileUtil.h"
#include "OSRMException.h"
#include "osrm_exception.hpp"
#include "simple_logger.hpp"
#include <osrm/ServerPaths.h>
@ -88,49 +88,49 @@ inline void populate_base_path(ServerPaths &server_paths)
SimpleLogger().Write() << "not a regular file";
}
throw OSRMException(".hsgr not found: " + path_iterator->second.string());
throw osrm::exception(".hsgr not found: " + path_iterator->second.string());
}
path_iterator = server_paths.find("nodesdata");
if (path_iterator == server_paths.end() ||
!boost::filesystem::is_regular_file(path_iterator->second))
{
throw OSRMException(".nodes not found");
throw osrm::exception(".nodes not found");
}
path_iterator = server_paths.find("edgesdata");
if (path_iterator == server_paths.end() ||
!boost::filesystem::is_regular_file(path_iterator->second))
{
throw OSRMException(".edges not found");
throw osrm::exception(".edges not found");
}
path_iterator = server_paths.find("geometries");
if (path_iterator == server_paths.end() ||
!boost::filesystem::is_regular_file(path_iterator->second))
{
throw OSRMException(".geometry not found");
throw osrm::exception(".geometry not found");
}
path_iterator = server_paths.find("ramindex");
if (path_iterator == server_paths.end() ||
!boost::filesystem::is_regular_file(path_iterator->second))
{
throw OSRMException(".ramIndex not found");
throw osrm::exception(".ramIndex not found");
}
path_iterator = server_paths.find("fileindex");
if (path_iterator == server_paths.end() ||
!boost::filesystem::is_regular_file(path_iterator->second))
{
throw OSRMException(".fileIndex not found");
throw osrm::exception(".fileIndex not found");
}
path_iterator = server_paths.find("namesdata");
if (path_iterator == server_paths.end() ||
!boost::filesystem::is_regular_file(path_iterator->second))
{
throw OSRMException(".namesIndex not found");
throw osrm::exception(".namesIndex not found");
}
SimpleLogger().Write() << "HSGR file:\t" << server_paths["hsgrdata"];
@ -261,7 +261,7 @@ inline unsigned GenerateServerProgramOptions(const int argc,
if (1 > requested_num_threads)
{
throw OSRMException("Number of threads must be a positive number");
throw osrm::exception("Number of threads must be a positive number");
}
if (!use_shared_memory && option_variables.count("base"))

View File

@ -1,39 +0,0 @@
/*
Copyright (c) 2013, Project OSRM, Dennis Luxen, others
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
Redistributions of source code must retain the above copyright notice, this list
of conditions and the following disclaimer.
Redistributions in binary form must reproduce the above copyright notice, this
list of conditions and the following disclaimer in the documentation and/or
other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef TIMINGUTIL_H
#define TIMINGUTIL_H
#include <chrono>
#define TIMER_START(_X) auto _X##_start = std::chrono::steady_clock::now(), _X##_stop = _X##_start
#define TIMER_STOP(_X) _X##_stop = std::chrono::steady_clock::now()
#define TIMER_MSEC(_X) std::chrono::duration_cast<std::chrono::milliseconds>(_X##_stop - _X##_start).count()
#define TIMER_SEC(_X) (0.001*std::chrono::duration_cast<std::chrono::milliseconds>(_X##_stop - _X##_start).count())
#define TIMER_MIN(_X) std::chrono::duration_cast<std::chrono::minutes>(_X##_stop - _X##_start).count()
#endif // TIMINGUTIL_H

View File

@ -722,7 +722,7 @@ constexpr unsigned short atan_table[4096] = {
// max value is pi/4
constexpr double SCALING_FACTOR = 4. / M_PI * 0xFFFF;
double atan2_lookup(double y, double x)
inline double atan2_lookup(double y, double x)
{
if (std::abs(x) < std::numeric_limits<double>::epsilon())
{

View File

@ -25,33 +25,41 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef MACHINE_INFO_H
#define MACHINE_INFO_H
#include "bearing.hpp"
enum Endianness
{ LittleEndian = 1,
BigEndian = 2 };
// Function is optimized to a single 'mov eax,1' on GCC, clang and icc using -O3
Endianness GetMachineEndianness()
std::string Bearing::Get(const double heading)
{
int i(1);
char *p = (char *)&i;
if (1 == p[0])
if (heading <= 202.5)
{
return LittleEndian;
if (heading >= 0. && heading <= 22.5)
{
return "N";
}
if (heading > 22.5 && heading <= 67.5)
{
return "NE";
}
if (heading > 67.5 && heading <= 112.5)
{
return "E";
}
if (heading > 112.5 && heading <= 157.5)
{
return "SE";
}
return "S";
}
return BigEndian;
}
// Reverses Network Byte Order into something usable, compiles down to a bswap-mov combination
unsigned SwapEndian(unsigned x)
{
if (GetMachineEndianness() == LittleEndian)
if (heading > 202.5 && heading <= 247.5)
{
return ((x >> 24) | ((x << 8) & 0x00FF0000) | ((x >> 8) & 0x0000FF00) | (x << 24));
return "SW";
}
return x;
if (heading > 247.5 && heading <= 292.5)
{
return "W";
}
if (heading > 292.5 && heading <= 337.5)
{
return "NW";
}
return "N";
}
#endif // MACHINE_INFO_H

38
Util/bearing.hpp Normal file
View File

@ -0,0 +1,38 @@
/*
Copyright (c) 2013, Project OSRM, Dennis Luxen, others
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
Redistributions of source code must retain the above copyright notice, this list
of conditions and the following disclaimer.
Redistributions in binary form must reproduce the above copyright notice, this
list of conditions and the following disclaimer in the documentation and/or
other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef BEARING_HPP_
#define BEARING_HPP_
#include <string>
struct Bearing
{
static std::string Get(const double heading);
};
#endif // BEARING_HPP_

View File

@ -145,7 +145,7 @@ struct cast
template <typename T> struct scientific_policy : boost::spirit::karma::real_policies<T>
{
// we want the numbers always to be in fixed format
static int floatfield(T n)
static int floatfield(T)
{
return boost::spirit::karma::real_policies<T>::fmtflags::fixed;
}

View File

@ -41,13 +41,13 @@ template <typename T> void sort_unique_resize(std::vector<T> &vector)
vector.resize(number_of_unique_elements);
}
// template <typename T> void sort_unique_resize_shrink_vector(std::vector<T> &vector)
// template <typename T> inline void sort_unique_resize_shrink_vector(std::vector<T> &vector)
// {
// sort_unique_resize(vector);
// vector.shrink_to_fit();
// }
// template <typename T> void remove_consecutive_duplicates_from_vector(std::vector<T> &vector)
// template <typename T> inline void remove_consecutive_duplicates_from_vector(std::vector<T> &vector)
// {
// const auto number_of_unique_elements = std::unique(vector.begin(), vector.end()) - vector.begin();
// vector.resize(number_of_unique_elements);
@ -71,5 +71,12 @@ Function for_each_pair(ForwardIterator begin, ForwardIterator end, Function func
}
return function;
}
template <class ContainerT, typename Function>
Function for_each_pair(ContainerT &container, Function function)
{
return for_each_pair(std::begin(container), std::end(container), function);
}
}
#endif /* CONTAINER_HPP_ */

View File

@ -27,7 +27,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "FingerPrint.h"
#include "OSRMException.h"
#include "osrm_exception.hpp"
#include <boost/uuid/name_generator.hpp>
@ -70,7 +70,7 @@ bool FingerPrint::TestGraphUtil(const FingerPrint &other) const
{
if (!other.IsMagicNumberOK())
{
throw OSRMException("hsgr input file misses magic number. Check or reprocess the file");
throw osrm::exception("hsgr input file misses magic number. Check or reprocess the file");
}
return std::equal(md5_graph, md5_graph + 32, other.md5_graph);
}
@ -79,7 +79,7 @@ bool FingerPrint::TestPrepare(const FingerPrint &other) const
{
if (!other.IsMagicNumberOK())
{
throw OSRMException("osrm input file misses magic number. Check or reprocess the file");
throw osrm::exception("osrm input file misses magic number. Check or reprocess the file");
}
return std::equal(md5_prepare, md5_prepare + 32, other.md5_prepare);
}
@ -88,7 +88,7 @@ bool FingerPrint::TestRTree(const FingerPrint &other) const
{
if (!other.IsMagicNumberOK())
{
throw OSRMException("r-tree input file misses magic number. Check or reprocess the file");
throw osrm::exception("r-tree input file misses magic number. Check or reprocess the file");
}
return std::equal(md5_tree, md5_tree + 32, other.md5_tree);
}
@ -97,7 +97,7 @@ bool FingerPrint::TestQueryObjects(const FingerPrint &other) const
{
if (!other.IsMagicNumberOK())
{
throw OSRMException("missing magic number. Check or reprocess the file");
throw osrm::exception("missing magic number. Check or reprocess the file");
}
return std::equal(md5_objects, md5_objects + 32, other.md5_objects);
}

View File

@ -1,6 +1,6 @@
/*
Copyright (c) 2013, Project OSRM, Dennis Luxen, others
Copyright (c) 2015, Project OSRM, Dennis Luxen, others
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
@ -25,5 +25,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "git_sha.hpp"
#define GIT_DESCRIPTION "${GIT_DESCRIPTION}"
char g_GIT_DESCRIPTION[] = GIT_DESCRIPTION;

View File

@ -1,6 +1,6 @@
/*
Copyright (c) 2013, Project OSRM, Dennis Luxen, others
Copyright (c) 2015, Project OSRM, Dennis Luxen, others
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
@ -25,9 +25,9 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef GIT_DESCRIPTION_H
#define GIT_DESCRIPTION_H
#ifndef GIT_SHA_HPP
#define GIT_SHA_HPP
extern char g_GIT_DESCRIPTION[];
#endif //GIT_DESCRIPTION_H
#endif //GIT_SHA_HPP

View File

@ -1,6 +1,6 @@
/*
Copyright (c) 2013, Project OSRM, Dennis Luxen, others
Copyright (c) 2015, Project OSRM, Dennis Luxen, others
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
@ -28,11 +28,11 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef GRAPHLOADER_H
#define GRAPHLOADER_H
#include "OSRMException.h"
#include "../DataStructures/ImportNode.h"
#include "../DataStructures/ImportEdge.h"
#include "../DataStructures/QueryNode.h"
#include "../DataStructures/Restriction.h"
#include "osrm_exception.hpp"
#include "../data_structures/external_memory_node.hpp"
#include "../data_structures/import_edge.hpp"
#include "../data_structures/query_node.hpp"
#include "../data_structures/restriction.hpp"
#include "../Util/simple_logger.hpp"
#include "../Util/FingerPrint.h"
#include "../typedefs.h"
@ -57,7 +57,7 @@ NodeID readBinaryOSRMGraphFromStream(std::istream &input_stream,
std::vector<EdgeT> &edge_list,
std::vector<NodeID> &barrier_node_list,
std::vector<NodeID> &traffic_light_node_list,
std::vector<NodeInfo> *int_to_ext_node_id_map,
std::vector<QueryNode> *int_to_ext_node_id_map,
std::vector<TurnRestriction> &restriction_list)
{
const FingerPrint fingerprint_orig;
@ -70,23 +70,23 @@ NodeID readBinaryOSRMGraphFromStream(std::istream &input_stream,
"Reprocess to get rid of this warning.";
}
NodeID n, source, target;
EdgeID m;
short dir; // direction (0 = open, 1 = forward, 2+ = open)
std::unordered_map<NodeID, NodeID> ext_to_int_id_map;
NodeID n;
input_stream.read((char *)&n, sizeof(NodeID));
SimpleLogger().Write() << "Importing n = " << n << " nodes ";
ExternalMemoryNode current_node;
for (NodeID i = 0; i < n; ++i)
{
input_stream.read((char *)&current_node, sizeof(ExternalMemoryNode));
int_to_ext_node_id_map->emplace_back(current_node.lat, current_node.lon, current_node.node_id);
ext_to_int_id_map.emplace(current_node.node_id, i);
if (current_node.bollard)
if (current_node.barrier)
{
barrier_node_list.emplace_back(i);
}
if (current_node.trafficLight)
if (current_node.traffic_lights)
{
traffic_light_node_list.emplace_back(i);
}
@ -95,41 +95,48 @@ NodeID readBinaryOSRMGraphFromStream(std::istream &input_stream,
// tighten vector sizes
barrier_node_list.shrink_to_fit();
traffic_light_node_list.shrink_to_fit();
input_stream.read((char *)&m, sizeof(unsigned));
SimpleLogger().Write() << " and " << m << " edges ";
// renumber nodes in turn restrictions
for (TurnRestriction &current_restriction : restriction_list)
{
auto internal_id_iter = ext_to_int_id_map.find(current_restriction.fromNode);
auto internal_id_iter = ext_to_int_id_map.find(current_restriction.from.node);
if (internal_id_iter == ext_to_int_id_map.end())
{
SimpleLogger().Write(logDEBUG) << "Unmapped from Node of restriction";
continue;
}
current_restriction.fromNode = internal_id_iter->second;
current_restriction.from.node = internal_id_iter->second;
internal_id_iter = ext_to_int_id_map.find(current_restriction.viaNode);
internal_id_iter = ext_to_int_id_map.find(current_restriction.via.node);
if (internal_id_iter == ext_to_int_id_map.end())
{
SimpleLogger().Write(logDEBUG) << "Unmapped via node of restriction";
continue;
}
current_restriction.viaNode = internal_id_iter->second;
current_restriction.via.node = internal_id_iter->second;
internal_id_iter = ext_to_int_id_map.find(current_restriction.toNode);
internal_id_iter = ext_to_int_id_map.find(current_restriction.to.node);
if (internal_id_iter == ext_to_int_id_map.end())
{
SimpleLogger().Write(logDEBUG) << "Unmapped to node of restriction";
continue;
}
current_restriction.toNode = internal_id_iter->second;
current_restriction.to.node = internal_id_iter->second;
}
edge_list.reserve(m);
EdgeWeight weight;
NodeID nameID;
NodeID source, target;
unsigned nameID;
int length;
short dir; // direction (0 = open, 1 = forward, 2+ = open)
bool is_roundabout, ignore_in_grid, is_access_restricted, is_split;
TravelMode travel_mode;
EdgeID m;
input_stream.read((char *)&m, sizeof(unsigned));
edge_list.reserve(m);
SimpleLogger().Write() << " and " << m << " edges ";
for (EdgeID i = 0; i < m; ++i)
{
input_stream.read((char *)&source, sizeof(unsigned));
@ -178,7 +185,8 @@ NodeID readBinaryOSRMGraphFromStream(std::istream &input_stream,
continue;
}
target = internal_id_iter->second;
BOOST_ASSERT_MSG(source != UINT_MAX && target != UINT_MAX, "nonexisting source or target");
BOOST_ASSERT_MSG(source != SPECIAL_NODEID && target != SPECIAL_NODEID,
"nonexisting source or target");
if (source > target)
{
@ -198,8 +206,10 @@ NodeID readBinaryOSRMGraphFromStream(std::istream &input_stream,
travel_mode,
is_split);
}
ext_to_int_id_map.clear();
tbb::parallel_sort(edge_list.begin(), edge_list.end());
for (unsigned i = 1; i < edge_list.size(); ++i)
{
if ((edge_list[i - 1].target == edge_list[i].target) &&
@ -210,22 +220,22 @@ NodeID readBinaryOSRMGraphFromStream(std::istream &input_stream,
(edge_list[i - 1].backward == edge_list[i].backward);
const bool edge_flags_are_superset1 =
(edge_list[i - 1].forward && edge_list[i - 1].backward) &&
(edge_list[i].backward != edge_list[i].backward);
(edge_list[i].forward != edge_list[i].backward);
const bool edge_flags_are_superset_2 =
(edge_list[i].forward && edge_list[i].backward) &&
(edge_list[i - 1].backward != edge_list[i - 1].backward);
(edge_list[i - 1].forward != edge_list[i - 1].backward);
if (edge_flags_equivalent)
{
edge_list[i].weight = std::min(edge_list[i - 1].weight, edge_list[i].weight);
edge_list[i - 1].source = UINT_MAX;
edge_list[i - 1].source = SPECIAL_NODEID;
}
else if (edge_flags_are_superset1)
{
if (edge_list[i - 1].weight <= edge_list[i].weight)
{
// edge i-1 is smaller and goes in both directions. Throw away the other edge
edge_list[i].source = UINT_MAX;
edge_list[i].source = SPECIAL_NODEID;
}
else
{
@ -247,132 +257,22 @@ NodeID readBinaryOSRMGraphFromStream(std::istream &input_stream,
else
{
// edge i is smaller and goes in both direction. Throw away edge i-1
edge_list[i - 1].source = UINT_MAX;
edge_list[i - 1].source = SPECIAL_NODEID;
}
}
}
}
const auto new_end_iter = std::remove_if(edge_list.begin(),
edge_list.end(),
[](const EdgeT &edge)
{ return edge.source == SPECIAL_NODEID; });
ext_to_int_id_map.clear();
const auto new_end_iter = std::remove_if(edge_list.begin(), edge_list.end(), [] (const EdgeT &edge)
{
return edge.source == SPECIAL_NODEID ||
edge.target == SPECIAL_NODEID;
});
edge_list.erase(new_end_iter, edge_list.end()); // remove excess candidates.
edge_list.shrink_to_fit();
SimpleLogger().Write() << "Graph loaded ok and has " << edge_list.size() << " edges";
return n;
}
template <typename EdgeT, typename CoordinateT>
NodeID readBinaryOSRMGraphFromStream(std::istream &input_stream,
std::vector<EdgeT> &edge_list,
std::vector<CoordinateT> & coordinate_list)
{
const FingerPrint fingerprint_orig;
FingerPrint fingerprint_loaded;
input_stream.read((char *)&fingerprint_loaded, sizeof(FingerPrint));
if (!fingerprint_loaded.TestGraphUtil(fingerprint_orig))
{
SimpleLogger().Write(logWARNING) << ".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)
std::unordered_map<NodeID, NodeID> ext_to_int_id_map;
input_stream.read((char *)&n, sizeof(NodeID));
SimpleLogger().Write() << "Importing n = " << n << " nodes ";
ExternalMemoryNode current_node;
for (NodeID i = 0; i < n; ++i)
{
input_stream.read((char *)&current_node, sizeof(ExternalMemoryNode));
coordinate_list.emplace_back(current_node.lat, current_node.lon);
ext_to_int_id_map.emplace(current_node.node_id, i);
}
input_stream.read((char *)&m, sizeof(unsigned));
SimpleLogger().Write() << " and " << m << " edges ";
edge_list.reserve(m);
EdgeWeight weight;
NodeID nameID;
int length;
bool is_roundabout, ignore_in_grid, is_access_restricted, is_split;
TravelMode travel_mode;
for (EdgeID i = 0; i < m; ++i)
{
input_stream.read((char *)&source, sizeof(unsigned));
input_stream.read((char *)&target, sizeof(unsigned));
input_stream.read((char *)&length, sizeof(int));
input_stream.read((char *)&dir, sizeof(short));
input_stream.read((char *)&weight, sizeof(int));
input_stream.read((char *)&nameID, sizeof(unsigned));
input_stream.read((char *)&is_roundabout, sizeof(bool));
input_stream.read((char *)&ignore_in_grid, sizeof(bool));
input_stream.read((char *)&is_access_restricted, sizeof(bool));
input_stream.read((char *)&travel_mode, sizeof(TravelMode));
input_stream.read((char *)&is_split, sizeof(bool));
BOOST_ASSERT_MSG(length > 0, "loaded null length edge");
BOOST_ASSERT_MSG(weight > 0, "loaded null weight");
BOOST_ASSERT_MSG(0 <= dir && dir <= 2, "loaded bogus direction");
// translate the external NodeIDs to internal IDs
auto internal_id_iter = ext_to_int_id_map.find(source);
if (ext_to_int_id_map.find(source) == ext_to_int_id_map.end())
{
#ifndef NDEBUG
SimpleLogger().Write(logWARNING) << " unresolved source NodeID: " << source;
#endif
continue;
}
source = internal_id_iter->second;
internal_id_iter = ext_to_int_id_map.find(target);
if (ext_to_int_id_map.find(target) == ext_to_int_id_map.end())
{
#ifndef NDEBUG
SimpleLogger().Write(logWARNING) << "unresolved target NodeID : " << target;
#endif
continue;
}
target = internal_id_iter->second;
BOOST_ASSERT_MSG(source != UINT_MAX && target != UINT_MAX, "nonexisting source or target");
if (source > target)
{
std::swap(source, target);
}
edge_list.emplace_back(source,
target);
}
tbb::parallel_sort(edge_list.begin(), edge_list.end());
for (unsigned i = 1; i < edge_list.size(); ++i)
{
if ((edge_list[i - 1].target == edge_list[i].target) &&
(edge_list[i - 1].source == edge_list[i].source))
{
edge_list[i].distance = std::min(edge_list[i - 1].distance, edge_list[i].distance);
edge_list[i - 1].source = UINT_MAX;
}
}
const auto new_end_iter = std::remove_if(edge_list.begin(),
edge_list.end(),
[](const EdgeT &edge)
{ return edge.source == SPECIAL_NODEID; });
ext_to_int_id_map.clear();
edge_list.erase(new_end_iter, edge_list.end()); // remove excess candidates.
edge_list.shrink_to_fit();
SimpleLogger().Write() << "Graph loaded ok and has " << n << " nodes and " << edge_list.size() << " edges";
return n;
}
template <typename NodeT, typename EdgeT>
unsigned readHSGRFromStream(const boost::filesystem::path &hsgr_file,
std::vector<NodeT> &node_list,
@ -381,11 +281,11 @@ unsigned readHSGRFromStream(const boost::filesystem::path &hsgr_file,
{
if (!boost::filesystem::exists(hsgr_file))
{
throw OSRMException("hsgr file does not exist");
throw osrm::exception("hsgr file does not exist");
}
if (0 == boost::filesystem::file_size(hsgr_file))
{
throw OSRMException("hsgr file is empty");
throw osrm::exception("hsgr file is empty");
}
boost::filesystem::ifstream hsgr_input_stream(hsgr_file, std::ios::binary);

View File

@ -25,8 +25,8 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef RANGE_H
#define RANGE_H
#ifndef INTEGER_RANGE_HPP
#define INTEGER_RANGE_HPP
#include <type_traits>
@ -58,10 +58,13 @@ template <typename Integer> class range
};
// convenience function to construct an integer range with type deduction
template <typename Integer> range<Integer> irange(Integer first, Integer last)
template <typename Integer>
range<Integer> irange(const Integer first,
const Integer last,
typename std::enable_if<std::is_integral<Integer>::value>::type * = 0)
{
return range<Integer>(first, last);
}
}
#endif // RANGE_H
#endif // INTEGER_RANGE_HPP

View File

@ -25,54 +25,48 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef HASH_TABLE_H
#define HASH_TABLE_H
#ifndef RANGE_HPP_
#define RANGE_HPP_
#include <vector>
template <typename Key, typename Value>
class HashTable
namespace osrm
{
namespace util
{
template <typename Iterator> class Range
{
private:
using KeyValPair = std::pair<Key, Value>;
std::vector<KeyValPair> table;
public:
HashTable() {}
Range(Iterator begin, Iterator end) : begin_(begin), end_(end) {}
inline void Add(Key const &key, Value const &value)
{
table.emplace_back(std::move(key), std::move(value));
}
Iterator begin() const { return begin_; }
Iterator end() const { return end_; }
inline void Clear()
{
table.clear();
}
inline const Value Find(Key const &key) const
{
for (const auto &key_val_pair : table)
{
if (key_val_pair.first == key)
{
return key_val_pair.second;
}
}
return Value();
}
inline const bool Holds(Key const &key) const
{
for (const auto &key_val_pair : table)
{
if (key_val_pair.first == key)
{
return true;
}
}
return false;
}
private:
Iterator begin_;
Iterator end_;
};
#endif /* HASH_TABLE_H */
// Convenience functions for template parameter inference,
// akin to std::make_pair.
template <typename Iterator> Range<Iterator> range(Iterator begin, Iterator end)
{
return Range<Iterator>(begin, end);
}
template <typename Reversable>
Range<typename Reversable::reverse_iterator> reverse(Reversable *reversable)
{
return Range<typename Reversable::reverse_iterator>(reversable->rbegin(), reversable->rend());
}
template <typename ConstReversable>
Range<typename ConstReversable::const_reverse_iterator>
const_reverse(const ConstReversable *const_reversable)
{
return Range<typename ConstReversable::const_reverse_iterator>(const_reversable->crbegin(),
const_reversable->crend());
}
}
}
#endif // RANGE_HPP_

View File

@ -1,6 +1,6 @@
/*
Copyright (c) 2013, Project OSRM, Dennis Luxen, others
Copyright (c) 2014, Project OSRM, Dennis Luxen, others
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
@ -28,67 +28,13 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// based on
// https://svn.apache.org/repos/asf/mesos/tags/release-0.9.0-incubating-RC0/src/common/json.hpp
#ifndef JSON_CONTAINER_H
#define JSON_CONTAINER_H
#ifndef JSON_RENDERER_HPP
#define JSON_RENDERER_HPP
#include "../ThirdParty/variant/variant.hpp"
#include "../Util/cast.hpp"
#include "../data_structures/json_container.hpp"
#include "cast.hpp"
#include <iostream>
#include <vector>
#include <string>
#include <unordered_map>
namespace JSON
{
struct Object;
struct Array;
struct String
{
String() {}
String(const char *value) : value(value) {}
String(const std::string &value) : value(value) {}
std::string value;
};
struct Number
{
Number() {}
Number(double value) : value(value) {}
double value;
};
struct True
{
};
struct False
{
};
struct Null
{
};
using Value = mapbox::util::variant<String,
Number,
mapbox::util::recursive_wrapper<Object>,
mapbox::util::recursive_wrapper<Array>,
True,
False,
Null>;
struct Object
{
std::unordered_map<std::string, Value> values;
};
struct Array
{
std::vector<Value> values;
};
namespace JSON {
struct Renderer : mapbox::util::static_visitor<>
{
@ -233,4 +179,4 @@ inline void render(std::vector<char> &out, const Object &object)
} // namespace JSON
#endif // JSON_CONTAINER_H
#endif // JSON_RENDERER_HPP

View File

@ -1,6 +1,6 @@
/*
Copyright (c) 2013, Project OSRM, Dennis Luxen, others
Copyright (c) 2014, Project OSRM, Dennis Luxen, others
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
@ -25,8 +25,8 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef LUA_UTIL_H
#define LUA_UTIL_H
#ifndef LUA_UTIL_HPP
#define LUA_UTIL_HPP
extern "C" {
#include <lua.h>
@ -63,4 +63,4 @@ inline void luaAddScriptFolderToLoadPath(lua_State *lua_state, const char *file_
luaL_dostring(lua_state, lua_code.c_str());
}
#endif // LUA_UTIL_H
#endif // LUA_UTIL_HPP

43
Util/osrm_exception.cpp Normal file
View File

@ -0,0 +1,43 @@
/*
Copyright (c) 2015, Project OSRM, Dennis Luxen, others
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
Redistributions of source code must retain the above copyright notice, this list
of conditions and the following disclaimer.
Redistributions in binary form must reproduce the above copyright notice, this
list of conditions and the following disclaimer in the documentation and/or
other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "osrm_exception.hpp"
namespace osrm
{
// This function exists to 'anchor' the class, and stop the compiler from
// copying vtable and RTTI info into every object file that includes
// this header. (Caught by -Wweak-vtables under Clang.)
// More information from the LLVM Coding Standards:
// If a class is defined in a header file and has a vtable (either it has
// virtual methods or it derives from classes with virtual methods), it must
// always have at least one out-of-line virtual method in the class. Without
// this, the compiler will copy the vtable and RTTI into every .o file that
// #includes the header, bloating .o file sizes and increasing link times.
void exception::anchor() const { }
}

View File

@ -1,6 +1,6 @@
/*
Copyright (c) 2013, Project OSRM, Dennis Luxen, others
Copyright (c) 2015, Project OSRM, Dennis Luxen, others
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
@ -25,22 +25,27 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef OSRM_EXCEPTION_H
#define OSRM_EXCEPTION_H
#ifndef OSRM_EXCEPTION_HPP
#define OSRM_EXCEPTION_HPP
#include <exception>
#include <string>
class OSRMException : public std::exception
namespace osrm
{
class exception final : public std::exception
{
public:
explicit OSRMException(const char *message) : message(message) {}
explicit OSRMException(const std::string &message) : message(message) {}
virtual ~OSRMException() throw() {}
explicit exception(const char *message) : message(message) {}
explicit exception(const std::string &message) : message(message) {}
private:
virtual const char *what() const throw() { return message.c_str(); }
// This function exists to 'anchor' the class, and stop the compiler from
// copying vtable and RTTI info into every object file that includes
// this header. (Caught by -Wweak-vtables under Clang.)
virtual void anchor() const;
const char *what() const noexcept { return message.c_str(); }
const std::string message;
};
#endif /* OSRM_EXCEPTION_H */
}
#endif /* OSRM_EXCEPTION_HPP */

42
Util/range_algorithms.hpp Normal file
View File

@ -0,0 +1,42 @@
/*
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 RANGE_ALGORITHMS_HPP
#define RANGE_ALGORITHMS_HPP
#include <algorithm>
namespace osrm {
template<class Container>
auto max_element(const Container & c) -> decltype(std::max_element(c.begin(), c.end()))
{
return std::max_element(c.begin(), c.end());
}
template<class Container>
auto max_element(const Container & c) -> decltype(std::max_element(c.cbegin(), c.cend()))
{
return std::max_element(c.cbegin(), c.cend());
}
}
#endif // RANGE_ALGORITHMS_HPP

View File

@ -1,6 +1,6 @@
/*
Copyright (c) 2013, Project OSRM, Dennis Luxen, others
Copyright (c) 2015, Project OSRM, Dennis Luxen, others
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
@ -27,7 +27,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "simple_logger.hpp"
#include "OSRMException.h"
#include "osrm_exception.hpp"
#include <boost/assert.hpp>
@ -74,16 +74,16 @@ SimpleLogger::SimpleLogger() : level(logINFO) {}
std::mutex &SimpleLogger::get_mutex()
{
static std::mutex m;
return m;
static std::mutex mtx;
return mtx;
}
std::ostringstream &SimpleLogger::Write(LogLevel l)
std::ostringstream &SimpleLogger::Write(LogLevel lvl)
{
std::lock_guard<std::mutex> lock(get_mutex());
try
{
level = l;
level = lvl;
os << "[";
switch (level)
{
@ -103,8 +103,8 @@ std::ostringstream &SimpleLogger::Write(LogLevel l)
}
catch (const std::exception &e)
{
// encapsulate in OSRMException
throw OSRMException(std::string(e.what()) + ", getting ostringstream");
// encapsulate in osrm::exception
throw osrm::exception(std::string(e.what()) + ", getting ostringstream");
}
return os;
}

View File

@ -67,8 +67,8 @@ class SimpleLogger
std::ostringstream &Write(LogLevel l = logINFO);
private:
LogLevel level;
std::ostringstream os;
LogLevel level;
};
#endif /* SIMPLE_LOGGER_HPP */

View File

@ -25,8 +25,8 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef STD_HASH_EXTENSIONS_H
#define STD_HASH_EXTENSIONS_H
#ifndef STD_HASH_HPP
#define STD_HASH_HPP
#include <functional>
@ -74,4 +74,4 @@ template <typename T1, typename T2> struct hash<std::pair<T1, T2>>
};
}
#endif // STD_HASH_EXTENSIONS_H
#endif // STD_HASH_HPP

View File

@ -25,13 +25,14 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef STRINGUTIL_H
#define STRINGUTIL_H
#ifndef STRING_UTIL_HPP
#define STRING_UTIL_HPP
#include <boost/algorithm/string.hpp>
#include <cstdio>
#include <cctype>
#include <random>
#include <string>
#include <vector>
@ -146,26 +147,4 @@ inline std::size_t URIDecode(const std::string &input, std::string &output)
inline std::size_t URIDecodeInPlace(std::string &URI) { return URIDecode(URI, URI); }
// TODO: remove after switch to libosmium
inline bool StringStartsWith(const std::string &input, const std::string &prefix)
{
return boost::starts_with(input, prefix);
}
inline std::string GetRandomString()
{
std::string s;
s.resize(128);
static const char alphanum[] = "0123456789"
"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
"abcdefghijklmnopqrstuvwxyz";
for (int i = 0; i < 127; ++i)
{
s[i] = alphanum[rand() % (sizeof(alphanum) - 1)];
}
s[127] = 0;
return s;
}
#endif // STRINGUTIL_H
#endif // STRING_UTIL_HPP

80
Util/timing_util.hpp Normal file
View File

@ -0,0 +1,80 @@
/*
Copyright (c) 2014, Project OSRM, Dennis Luxen, others
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
Redistributions of source code must retain the above copyright notice, this list
of conditions and the following disclaimer.
Redistributions in binary form must reproduce the above copyright notice, this
list of conditions and the following disclaimer in the documentation and/or
other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef TIMING_UTIL_HPP
#define TIMING_UTIL_HPP
#include <atomic>
#include <chrono>
#include <cstdint>
#include <mutex>
#include <unordered_map>
struct GlobalTimer
{
GlobalTimer() : time(0) {}
std::atomic<uint64_t> time;
};
class GlobalTimerFactory
{
public:
static GlobalTimerFactory& get()
{
static GlobalTimerFactory instance;
return instance;
}
GlobalTimer& getGlobalTimer(const std::string& name)
{
std::lock_guard<std::mutex> lock(map_mutex);
return timer_map[name];
}
private:
std::mutex map_mutex;
std::unordered_map<std::string, GlobalTimer> timer_map;
};
#define GLOBAL_TIMER_AQUIRE(_X) auto& _X##_global_timer = GlobalTimerFactory::get().getGlobalTimer(#_X)
#define GLOBAL_TIMER_RESET(_X) _X##_global_timer.time = 0
#define GLOBAL_TIMER_START(_X) TIMER_START(_X)
#define GLOBAL_TIMER_STOP(_X) TIMER_STOP(_X); _X##_global_timer.time += TIMER_NSEC(_X)
#define GLOBAL_TIMER_NSEC(_X) static_cast<double>(_X##_global_timer.time)
#define GLOBAL_TIMER_USEC(_X) (_X##_global_timer.time / 1000.0)
#define GLOBAL_TIMER_MSEC(_X) (_X##_global_timer.time / 1000.0 / 1000.0)
#define GLOBAL_TIMER_SEC(_X) (_X##_global_timer.time / 1000.0 / 1000.0 / 1000.0)
#define TIMER_START(_X) auto _X##_start = std::chrono::steady_clock::now(), _X##_stop = _X##_start
#define TIMER_STOP(_X) _X##_stop = std::chrono::steady_clock::now()
#define TIMER_NSEC(_X) std::chrono::duration_cast<std::chrono::nanoseconds>(_X##_stop - _X##_start).count()
#define TIMER_USEC(_X) std::chrono::duration_cast<std::chrono::microseconds>(_X##_stop - _X##_start).count()
#define TIMER_MSEC(_X) (0.000001*std::chrono::duration_cast<std::chrono::nanoseconds>(_X##_stop - _X##_start).count())
#define TIMER_SEC(_X) (0.000001*std::chrono::duration_cast<std::chrono::microseconds>(_X##_stop - _X##_start).count())
#define TIMER_MIN(_X) std::chrono::duration_cast<std::chrono::minutes>(_X##_stop - _X##_start).count()
#endif // TIMING_UTIL_HPP

140
Util/xml_renderer.hpp Normal file
View File

@ -0,0 +1,140 @@
/*
Copyright (c) 2014, Project OSRM, Dennis Luxen, others
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
Redistributions of source code must retain the above copyright notice, this list
of conditions and the following disclaimer.
Redistributions in binary form must reproduce the above copyright notice, this
list of conditions and the following disclaimer in the documentation and/or
other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef XML_RENDERER_HPP
#define XML_RENDERER_HPP
#include "../data_structures/json_container.hpp"
#include "cast.hpp"
namespace JSON {
struct XMLToArrayRenderer : mapbox::util::static_visitor<>
{
explicit XMLToArrayRenderer(std::vector<char> &_out) : out(_out) {}
void operator()(const String &string) const
{
out.push_back('\"');
out.insert(out.end(), string.value.begin(), string.value.end());
out.push_back('\"');
}
void operator()(const Number &number) const
{
const std::string number_string = cast::double_fixed_to_string(number.value);
out.insert(out.end(), number_string.begin(), number_string.end());
}
void operator()(const Object &object) const
{
auto iterator = object.values.begin();
while (iterator != object.values.end())
{
if (iterator->first.at(0) != '_')
{
out.push_back('<');
out.insert(out.end(), (*iterator).first.begin(), (*iterator).first.end());
}
else
{
out.push_back(' ');
out.insert(out.end(), ++(*iterator).first.begin(), (*iterator).first.end());
out.push_back('=');
}
mapbox::util::apply_visitor(XMLToArrayRenderer(out), (*iterator).second);
if (iterator->first.at(0) != '_')
{
out.push_back('/');
out.push_back('>');
}
++iterator;
}
}
void operator()(const Array &array) const
{
std::vector<Value>::const_iterator iterator;
iterator = array.values.begin();
while (iterator != array.values.end())
{
mapbox::util::apply_visitor(XMLToArrayRenderer(out), *iterator);
++iterator;
}
}
void operator()(const True &) const
{
const std::string temp("true");
out.insert(out.end(), temp.begin(), temp.end());
}
void operator()(const False &) const
{
const std::string temp("false");
out.insert(out.end(), temp.begin(), temp.end());
}
void operator()(const Null &) const
{
const std::string temp("null");
out.insert(out.end(), temp.begin(), temp.end());
}
private:
std::vector<char> &out;
};
template<class JSONObject>
inline void xml_render(std::vector<char> &out, const JSONObject &object)
{
Value value = object;
mapbox::util::apply_visitor(XMLToArrayRenderer(out), value);
}
template<class JSONObject>
inline void gpx_render(std::vector<char> &out, const JSONObject &object)
{
// add header
const std::string header {"<?xml version=\"1.0\" encoding=\"UTF-8\"?><gpx creator=\"OSRM Routing Engine\""
" version=\"1.1\" xmlns=\"http://www.topografix.com/GPX/1/1\" xmlns:xsi=\"http:"
"//www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"http://www.topogr"
"afix.com/GPX/1/1 gpx.xsd\"><metadata><copyright author=\"Project OSRM\"><lice"
"nse>Data (c) OpenStreetMap contributors (ODbL)</license></copyright></metadat"
"a><rte>"};
out.insert(out.end(), header.begin(), header.end());
xml_render(out, object);
const std::string footer {"</rte></gpx>"};
out.insert(out.end(), footer.begin(), footer.end());
}
} // namespace JSON
#endif // XML_RENDERER_HPP

View File

@ -1,8 +1,35 @@
#ifndef BFS_COMPONENT_EXPLORER_H_
#define BFS_COMPONENT_EXPLORER_H_
/*
Copyright (c) 2014, Project OSRM, Dennis Luxen, others
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
Redistributions of source code must retain the above copyright notice, this list
of conditions and the following disclaimer.
Redistributions in binary form must reproduce the above copyright notice, this
list of conditions and the following disclaimer in the documentation and/or
other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef BFS_COMPONENTS_HPP_
#define BFS_COMPONENTS_HPP_
#include "../typedefs.h"
#include "../DataStructures/RestrictionMap.h"
#include "../data_structures/restriction_map.hpp"
#include <queue>
#include <unordered_set>
@ -95,38 +122,38 @@ template <typename GraphT> class BFSComponentExplorer
const NodeID u = current_queue_item.second; // parent
// increment size counter of current component
++current_component_size;
const bool is_barrier_node = (m_barrier_nodes.find(v) != m_barrier_nodes.end());
if (!is_barrier_node)
if (m_barrier_nodes.find(v) != m_barrier_nodes.end())
{
const NodeID to_node_of_only_restriction =
m_restriction_map.CheckForEmanatingIsOnlyTurn(u, v);
continue;
}
const NodeID to_node_of_only_restriction =
m_restriction_map.CheckForEmanatingIsOnlyTurn(u, v);
for (auto e2 : m_graph.GetAdjacentEdgeRange(v))
for (auto e2 : m_graph.GetAdjacentEdgeRange(v))
{
const NodeID w = m_graph.GetTarget(e2);
if (to_node_of_only_restriction != std::numeric_limits<unsigned>::max() &&
w != to_node_of_only_restriction)
{
const NodeID w = m_graph.GetTarget(e2);
// At an only_-restriction but not at the right turn
continue;
}
if (to_node_of_only_restriction != std::numeric_limits<unsigned>::max() &&
w != to_node_of_only_restriction)
if (u != w)
{
// only add an edge if turn is not a U-turn except
// when it is at the end of a dead-end street.
if (!m_restriction_map.CheckIfTurnIsRestricted(u, v, w))
{
// At an only_-restriction but not at the right turn
continue;
}
if (u != w)
{
// only add an edge if turn is not a U-turn except
// when it is at the end of a dead-end street.
if (!m_restriction_map.CheckIfTurnIsRestricted(u, v, w))
// only add an edge if turn is not prohibited
if (std::numeric_limits<unsigned>::max() == m_component_index_list[w])
{
// only add an edge if turn is not prohibited
if (std::numeric_limits<unsigned>::max() == m_component_index_list[w])
{
// insert next (node, parent) only if w has
// not yet been explored
// mark node as read
m_component_index_list[w] = current_component;
bfs_queue.emplace(w, v);
}
// insert next (node, parent) only if w has
// not yet been explored
// mark node as read
m_component_index_list[w] = current_component;
bfs_queue.emplace(w, v);
}
}
}
@ -144,4 +171,4 @@ template <typename GraphT> class BFSComponentExplorer
const std::unordered_set<NodeID> &m_barrier_nodes;
};
#endif // BFS_COMPONENT_EXPLORER_H_
#endif // BFS_COMPONENTS_HPP_

View File

@ -1,6 +1,6 @@
/*
Copyright (c) 2013, Project OSRM, Dennis Luxen, others
Copyright (c) 2014, Project OSRM, Dennis Luxen, others
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
@ -25,10 +25,10 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "DouglasPeucker.h"
#include "douglas_peucker.hpp"
#include "../DataStructures/Range.h"
#include "../DataStructures/SegmentInformation.h"
#include "../data_structures/segment_information.hpp"
#include "../Util/integer_range.hpp"
#include <osrm/Coordinate.h>
@ -38,7 +38,8 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <algorithm>
namespace {
namespace
{
struct CoordinatePairCalculator
{
CoordinatePairCalculator() = delete;
@ -82,61 +83,40 @@ struct CoordinatePairCalculator
};
}
DouglasPeucker::DouglasPeucker()
: douglas_peucker_thresholds({512440, // z0
256720, // z1
122560, // z2
56780, // z3
28800, // z4
14400, // z5
7200, // z6
3200, // z7
2400, // z8
1000, // z9
600, // z10
120, // z11
60, // z12
45, // z13
36, // z14
20, // z15
8, // z16
6, // z17
4 // z18
})
{
}
void DouglasPeucker::Run(std::vector<SegmentInformation> &input_geometry, const unsigned zoom_level)
{
// check if input data is invalid
BOOST_ASSERT_MSG(!input_geometry.empty(), "geometry invalid");
Run(std::begin(input_geometry), std::end(input_geometry), zoom_level);
}
if (input_geometry.size() < 2)
void DouglasPeucker::Run(RandomAccessIt begin, RandomAccessIt end, const unsigned zoom_level)
{
unsigned size = std::distance(begin, end);
if (size < 2)
{
return;
}
input_geometry.front().necessary = true;
input_geometry.back().necessary = true;
begin->necessary = true;
std::prev(end)->necessary = true;
{
BOOST_ASSERT_MSG(zoom_level < 19, "unsupported zoom level");
unsigned left_border = 0;
unsigned right_border = 1;
BOOST_ASSERT_MSG(zoom_level < DOUGLAS_PEUCKER_THRESHOLDS.size(), "unsupported zoom level");
RandomAccessIt left_border = begin;
RandomAccessIt right_border = std::next(begin);
// Sweep over array and identify those ranges that need to be checked
do
{
// traverse list until new border element found
if (input_geometry[right_border].necessary)
if (right_border->necessary)
{
// sanity checks
BOOST_ASSERT(input_geometry[left_border].necessary);
BOOST_ASSERT(input_geometry[right_border].necessary);
BOOST_ASSERT(left_border->necessary);
BOOST_ASSERT(right_border->necessary);
recursion_stack.emplace(left_border, right_border);
left_border = right_border;
}
++right_border;
} while (right_border < input_geometry.size());
} while (right_border != end);
}
// mark locations as 'necessary' by divide-and-conquer
@ -146,40 +126,40 @@ void DouglasPeucker::Run(std::vector<SegmentInformation> &input_geometry, const
const GeometryRange pair = recursion_stack.top();
recursion_stack.pop();
// sanity checks
BOOST_ASSERT_MSG(input_geometry[pair.first].necessary, "left border mus be necessary");
BOOST_ASSERT_MSG(input_geometry[pair.second].necessary, "right border must be necessary");
BOOST_ASSERT_MSG(pair.second < input_geometry.size(), "right border outside of geometry");
BOOST_ASSERT_MSG(pair.first < pair.second, "left border on the wrong side");
BOOST_ASSERT_MSG(pair.first->necessary, "left border must be necessary");
BOOST_ASSERT_MSG(pair.second->necessary, "right border must be necessary");
BOOST_ASSERT_MSG(std::distance(pair.second, end) > 0, "right border outside of geometry");
BOOST_ASSERT_MSG(std::distance(pair.first, pair.second) >= 0,
"left border on the wrong side");
int max_int_distance = 0;
unsigned farthest_entry_index = pair.second;
const CoordinatePairCalculator dist_calc(input_geometry[pair.first].location,
input_geometry[pair.second].location);
auto farthest_entry_it = pair.second;
const CoordinatePairCalculator dist_calc(pair.first->location, pair.second->location);
// sweep over range to find the maximum
for (const auto i : osrm::irange(pair.first + 1, pair.second))
for (auto it = std::next(pair.first); it != pair.second; ++it)
{
const int distance = dist_calc(input_geometry[i].location);
const int distance = dist_calc(it->location);
// found new feasible maximum?
if (distance > max_int_distance && distance > douglas_peucker_thresholds[zoom_level])
if (distance > max_int_distance && distance > DOUGLAS_PEUCKER_THRESHOLDS[zoom_level])
{
farthest_entry_index = i;
farthest_entry_it = it;
max_int_distance = distance;
}
}
// check if maximum violates a zoom level dependent threshold
if (max_int_distance > douglas_peucker_thresholds[zoom_level])
if (max_int_distance > DOUGLAS_PEUCKER_THRESHOLDS[zoom_level])
{
// mark idx as necessary
input_geometry[farthest_entry_index].necessary = true;
if (1 < (farthest_entry_index - pair.first))
farthest_entry_it->necessary = true;
if (1 < std::distance(pair.first, farthest_entry_it))
{
recursion_stack.emplace(pair.first, farthest_entry_index);
recursion_stack.emplace(pair.first, farthest_entry_it);
}
if (1 < (pair.second - farthest_entry_index))
if (1 < std::distance(farthest_entry_it, pair.second))
{
recursion_stack.emplace(farthest_entry_index, pair.second);
recursion_stack.emplace(farthest_entry_it, pair.second);
}
}
}

View File

@ -25,12 +25,12 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef DOUGLASPEUCKER_H_
#define DOUGLASPEUCKER_H_
#ifndef DOUGLAS_PEUCKER_HPP_
#define DOUGLAS_PEUCKER_HPP_
#include <stack>
#include <utility>
#include <vector>
#include <array>
/* This class object computes the bitvector of indicating generalized input
* points according to the (Ramer-)Douglas-Peucker algorithm.
@ -41,18 +41,40 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
struct SegmentInformation;
static const std::array<int, 19> DOUGLAS_PEUCKER_THRESHOLDS {{
512440, // z0
256720, // z1
122560, // z2
56780, // z3
28800, // z4
14400, // z5
7200, // z6
3200, // z7
2400, // z8
1000, // z9
600, // z10
120, // z11
60, // z12
45, // z13
36, // z14
20, // z15
8, // z16
6, // z17
4 // z18
}};
class DouglasPeucker
{
private:
std::vector<int> douglas_peucker_thresholds;
public:
using RandomAccessIt = std::vector<SegmentInformation>::iterator;
using GeometryRange = std::pair<unsigned, unsigned>;
using GeometryRange = std::pair<RandomAccessIt, RandomAccessIt>;
// Stack to simulate the recursion
std::stack<GeometryRange> recursion_stack;
public:
DouglasPeucker();
void Run(RandomAccessIt begin, RandomAccessIt end, const unsigned zoom_level);
void Run(std::vector<SegmentInformation> &input_geometry, const unsigned zoom_level);
};
#endif /* DOUGLASPEUCKER_H_ */
#endif /* DOUGLAS_PEUCKER_HPP_ */

View File

@ -25,10 +25,10 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef OBJECT_TO_BASE64_H_
#define OBJECT_TO_BASE64_H_
#ifndef OBJECT_ENCODER_HPP
#define OBJECT_ENCODER_HPP
#include "../Util/StringUtil.h"
#include "../Util/string_util.hpp"
#include <boost/assert.hpp>
#include <boost/archive/iterators/base64_from_binary.hpp>
@ -91,4 +91,4 @@ struct ObjectEncoder
}
};
#endif /* OBJECT_TO_BASE64_H_ */
#endif /* OBJECT_ENCODER_HPP */

View File

@ -1,6 +1,6 @@
/*
Copyright (c) 2013, Project OSRM, Dennis Luxen, others
Copyright (c) 2014, Project OSRM, Dennis Luxen, others
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
@ -25,16 +25,16 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "PolylineCompressor.h"
#include "../DataStructures/SegmentInformation.h"
#include "polyline_compressor.hpp"
#include "../data_structures/segment_information.hpp"
#include <osrm/Coordinate.h>
void PolylineCompressor::encodeVectorSignedNumber(std::vector<int> &numbers,
std::string &output) const
std::string PolylineCompressor::encode_vector(std::vector<int> &numbers) const
{
const unsigned end = static_cast<unsigned>(numbers.size());
for (unsigned i = 0; i < end; ++i)
std::string output;
const auto end = numbers.size();
for (std::size_t i = 0; i < end; ++i)
{
numbers[i] <<= 1;
if (numbers[i] < 0)
@ -44,12 +44,14 @@ void PolylineCompressor::encodeVectorSignedNumber(std::vector<int> &numbers,
}
for (const int number : numbers)
{
encodeNumber(number, output);
output += encode_number(number);
}
return output;
}
void PolylineCompressor::encodeNumber(int number_to_encode, std::string &output) const
std::string PolylineCompressor::encode_number(int number_to_encode) const
{
std::string output;
while (number_to_encode >= 0x20)
{
const int next_value = (0x20 | (number_to_encode & 0x1f)) + 63;
@ -67,46 +69,30 @@ void PolylineCompressor::encodeNumber(int number_to_encode, std::string &output)
{
output += static_cast<char>(number_to_encode);
}
return output;
}
JSON::String
PolylineCompressor::printEncodedString(const std::vector<SegmentInformation> &polyline) const
std::string
PolylineCompressor::get_encoded_string(const std::vector<SegmentInformation> &polyline) const
{
std::string output;
std::vector<int> delta_numbers;
if (!polyline.empty())
if (polyline.empty())
{
FixedPointCoordinate last_coordinate = {0, 0};
for (const auto &segment : polyline)
{
if (segment.necessary)
{
const int lat_diff = segment.location.lat - last_coordinate.lat;
const int lon_diff = segment.location.lon - last_coordinate.lon;
delta_numbers.emplace_back(lat_diff);
delta_numbers.emplace_back(lon_diff);
last_coordinate = segment.location;
}
}
encodeVectorSignedNumber(delta_numbers, output);
return {};
}
JSON::String return_value(output);
return return_value;
}
JSON::Array
PolylineCompressor::printUnencodedString(const std::vector<SegmentInformation> &polyline) const
{
JSON::Array json_geometry_array;
std::vector<int> delta_numbers;
delta_numbers.reserve((polyline.size() - 1) * 2);
FixedPointCoordinate previous_coordinate = {0, 0};
for (const auto &segment : polyline)
{
if (segment.necessary)
{
JSON::Array json_coordinate;
json_coordinate.values.push_back(segment.location.lat / COORDINATE_PRECISION);
json_coordinate.values.push_back(segment.location.lon / COORDINATE_PRECISION);
json_geometry_array.values.push_back(json_coordinate);
const int lat_diff = segment.location.lat - previous_coordinate.lat;
const int lon_diff = segment.location.lon - previous_coordinate.lon;
delta_numbers.emplace_back(lat_diff);
delta_numbers.emplace_back(lon_diff);
previous_coordinate = segment.location;
}
}
return json_geometry_array;
return encode_vector(delta_numbers);
}

View File

@ -30,22 +30,18 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
struct SegmentInformation;
#include "../DataStructures/JSONContainer.h"
#include <string>
#include <vector>
class PolylineCompressor
{
private:
void encodeVectorSignedNumber(std::vector<int> &numbers, std::string &output) const;
std::string encode_vector(std::vector<int> &numbers) const;
void encodeNumber(int number_to_encode, std::string &output) const;
std::string encode_number(const int number_to_encode) const;
public:
JSON::String printEncodedString(const std::vector<SegmentInformation> &polyline) const;
JSON::Array printUnencodedString(const std::vector<SegmentInformation> &polyline) const;
std::string get_encoded_string(const std::vector<SegmentInformation> &polyline) const;
};
#endif /* POLYLINECOMPRESSOR_H_ */

View File

@ -0,0 +1,56 @@
/*
Copyright (c) 2014, Project OSRM, Dennis Luxen, others
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
Redistributions of source code must retain the above copyright notice, this list
of conditions and the following disclaimer.
Redistributions in binary form must reproduce the above copyright notice, this
list of conditions and the following disclaimer in the documentation and/or
other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "polyline_formatter.hpp"
#include "polyline_compressor.hpp"
#include "../data_structures/segment_information.hpp"
#include <osrm/Coordinate.h>
JSON::String
PolylineFormatter::printEncodedString(const std::vector<SegmentInformation> &polyline) const
{
return JSON::String(PolylineCompressor().get_encoded_string(polyline));
}
JSON::Array
PolylineFormatter::printUnencodedString(const std::vector<SegmentInformation> &polyline) const
{
JSON::Array json_geometry_array;
for (const auto &segment : polyline)
{
if (segment.necessary)
{
JSON::Array json_coordinate;
json_coordinate.values.push_back(segment.location.lat / COORDINATE_PRECISION);
json_coordinate.values.push_back(segment.location.lon / COORDINATE_PRECISION);
json_geometry_array.values.push_back(json_coordinate);
}
}
return json_geometry_array;
}

View File

@ -0,0 +1,45 @@
/*
Copyright (c) 2014, Project OSRM, Dennis Luxen, others
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
Redistributions of source code must retain the above copyright notice, this list
of conditions and the following disclaimer.
Redistributions in binary form must reproduce the above copyright notice, this
list of conditions and the following disclaimer in the documentation and/or
other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef POLYLINE_FORMATTER_HPP
#define POLYLINE_FORMATTER_HPP
struct SegmentInformation;
#include "../data_structures/json_container.hpp"
#include <string>
#include <vector>
struct PolylineFormatter
{
JSON::String printEncodedString(const std::vector<SegmentInformation> &polyline) const;
JSON::Array printUnencodedString(const std::vector<SegmentInformation> &polyline) const;
};
#endif /* POLYLINE_FORMATTER_HPP */

View File

@ -0,0 +1,253 @@
/*
Copyright (c) 2015, Project OSRM, Dennis Luxen, others
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
Redistributions of source code must retain the above copyright notice, this list
of conditions and the following disclaimer.
Redistributions in binary form must reproduce the above copyright notice, this
list of conditions and the following disclaimer in the documentation and/or
other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef TINY_COMPONENTS_HPP
#define TINY_COMPONENTS_HPP
#include "../typedefs.h"
#include "../data_structures/deallocating_vector.hpp"
#include "../data_structures/import_edge.hpp"
#include "../data_structures/query_node.hpp"
#include "../data_structures/percent.hpp"
#include "../data_structures/restriction.hpp"
#include "../data_structures/restriction_map.hpp"
#include "../data_structures/turn_instructions.hpp"
#include "../Util/integer_range.hpp"
#include "../Util/simple_logger.hpp"
#include "../Util/std_hash.hpp"
#include "../Util/timing_util.hpp"
#include <osrm/Coordinate.h>
#include <boost/assert.hpp>
#include <tbb/parallel_sort.h>
#include <cstdint>
#include <memory>
#include <stack>
#include <unordered_map>
#include <unordered_set>
#include <vector>
template <typename GraphT>
class TarjanSCC
{
struct TarjanStackFrame
{
explicit TarjanStackFrame(NodeID v, NodeID parent) : v(v), parent(parent) {}
NodeID v;
NodeID parent;
};
struct TarjanNode
{
TarjanNode() : index(SPECIAL_NODEID), low_link(SPECIAL_NODEID), on_stack(false) {}
unsigned index;
unsigned low_link;
bool on_stack;
};
std::vector<unsigned> components_index;
std::vector<NodeID> component_size_vector;
std::shared_ptr<GraphT> m_node_based_graph;
std::unordered_set<NodeID> barrier_node_set;
RestrictionMap m_restriction_map;
unsigned size_one_counter;
public:
template<class ContainerT>
TarjanSCC(std::shared_ptr<GraphT> graph,
const RestrictionMap &restrictions,
const ContainerT &barrier_node_list)
: components_index(graph->GetNumberOfNodes(), SPECIAL_NODEID),
m_node_based_graph(graph), m_restriction_map(restrictions),
size_one_counter(0)
{
barrier_node_set.insert(std::begin(barrier_node_list), std::end(barrier_node_list));
BOOST_ASSERT(m_node_based_graph->GetNumberOfNodes() > 0);
}
void run()
{
TIMER_START(SCC_RUN);
// The following is a hack to distinguish between stuff that happens
// before the recursive call and stuff that happens after
std::stack<TarjanStackFrame> recursion_stack;
// true = stuff before, false = stuff after call
std::stack<NodeID> tarjan_stack;
std::vector<TarjanNode> tarjan_node_list(m_node_based_graph->GetNumberOfNodes());
unsigned component_index = 0, size_of_current_component = 0;
int index = 0;
const NodeID last_node = m_node_based_graph->GetNumberOfNodes();
std::vector<bool> processing_node_before_recursion(m_node_based_graph->GetNumberOfNodes(), true);
for(const NodeID node : osrm::irange(0u, last_node))
{
if (SPECIAL_NODEID == components_index[node])
{
recursion_stack.emplace(TarjanStackFrame(node, node));
}
while (!recursion_stack.empty())
{
TarjanStackFrame currentFrame = recursion_stack.top();
const NodeID u = currentFrame.parent;
const NodeID v = currentFrame.v;
recursion_stack.pop();
const bool before_recursion = processing_node_before_recursion[v];
if (before_recursion && tarjan_node_list[v].index != UINT_MAX)
{
continue;
}
if (before_recursion)
{
// Mark frame to handle tail of recursion
recursion_stack.emplace(currentFrame);
processing_node_before_recursion[v] = false;
// Mark essential information for SCC
tarjan_node_list[v].index = index;
tarjan_node_list[v].low_link = index;
tarjan_stack.push(v);
tarjan_node_list[v].on_stack = true;
++index;
const NodeID to_node_of_only_restriction =
m_restriction_map.CheckForEmanatingIsOnlyTurn(u, v);
for (const auto current_edge : m_node_based_graph->GetAdjacentEdgeRange(v))
{
const auto vprime = m_node_based_graph->GetTarget(current_edge);
// Traverse outgoing edges
if (barrier_node_set.find(v) != barrier_node_set.end() &&
u != vprime)
{
// continue;
}
if (to_node_of_only_restriction != std::numeric_limits<unsigned>::max() &&
vprime == to_node_of_only_restriction)
{
// At an only_-restriction but not at the right turn
// continue;
}
if (m_restriction_map.CheckIfTurnIsRestricted(u, v, vprime))
{
// continue;
}
if (SPECIAL_NODEID == tarjan_node_list[vprime].index)
{
recursion_stack.emplace(TarjanStackFrame(vprime, v));
}
else
{
if (tarjan_node_list[vprime].on_stack &&
tarjan_node_list[vprime].index < tarjan_node_list[v].low_link)
{
tarjan_node_list[v].low_link = tarjan_node_list[vprime].index;
}
}
}
}
else
{
processing_node_before_recursion[v] = true;
tarjan_node_list[currentFrame.parent].low_link =
std::min(tarjan_node_list[currentFrame.parent].low_link,
tarjan_node_list[v].low_link);
// after recursion, lets do cycle checking
// Check if we found a cycle. This is the bottom part of the recursion
if (tarjan_node_list[v].low_link == tarjan_node_list[v].index)
{
NodeID vprime;
do
{
vprime = tarjan_stack.top();
tarjan_stack.pop();
tarjan_node_list[vprime].on_stack = false;
components_index[vprime] = component_index;
++size_of_current_component;
} while (v != vprime);
component_size_vector.emplace_back(size_of_current_component);
if (size_of_current_component > 1000)
{
SimpleLogger().Write() << "large component [" << component_index
<< "]=" << size_of_current_component;
}
++component_index;
size_of_current_component = 0;
}
}
}
}
TIMER_STOP(SCC_RUN);
SimpleLogger().Write() << "SCC run took: " << TIMER_MSEC(SCC_RUN)/1000. << "s";
size_one_counter = std::count_if(component_size_vector.begin(),
component_size_vector.end(),
[](unsigned value)
{
return 1 == value;
});
}
std::size_t get_number_of_components() const
{
return component_size_vector.size();
}
unsigned get_size_one_count() const
{
return size_one_counter;
}
unsigned get_component_size(const NodeID node) const
{
return component_size_vector[components_index[node]];
}
unsigned get_component_id(const NodeID node) const
{
return components_index[node];
}
};
#endif /* TINY_COMPONENTS_HPP */

View File

@ -38,13 +38,18 @@ build_script:
- SET P=c:/projects/osrm
- set TBB_INSTALL_DIR=%P%/tbb
- set TBB_ARCH_PLATFORM=intel64/vc12
- cmake .. -G "Visual Studio 12 Win64" -DCMAKE_BUILD_TYPE=%Configuration% -DBZIP2_INCLUDE_DIR=%P%/libs/include -DBZIP2_LIBRARIES=%P%/libs/lib/libbz2.lib -DCMAKE_INSTALL_PREFIX=%P%/libs -DBOOST_ROOT=%P%/boost_min -DBoost_USE_STATIC_LIBS=ON -T CTP_Nov2013
- cmake .. -G "Visual Studio 12 Win64" -DCMAKE_BUILD_TYPE=%Configuration% -DCMAKE_INSTALL_PREFIX=%P%/libs -DBOOST_ROOT=%P%/boost_min -DBoost_ADDITIONAL_VERSIONS=1.57 -DBoost_USE_STATIC_LIBS=ON -T CTP_Nov2013
- msbuild /clp:Verbosity=minimal /nologo OSRM.sln
- msbuild /clp:Verbosity=minimal /nologo tests.vcxproj
- cd %Configuration%
- if "%APPVEYOR_REPO_BRANCH%"=="develop" (7z a %P%/osrm_%Configuration%.zip *.exe *.pdb %P%/libs/bin/*.dll -tzip)
- cd ..\..\profiles
- echo disk=c:\temp\stxxl,10000,wincall > .stxxl.txt
- if "%APPVEYOR_REPO_BRANCH%"=="develop" (7z a %P%/osrm_%Configuration%.zip * -tzip)
- set PATH=%PATH%;c:/projects/osrm/libs/bin
- cd c:/projects/osrm/build/%Configuration%
- datastructure-tests.exe
- algorithm-tests.exe
test: off

189
benchmarks/static_rtree.cpp Normal file
View File

@ -0,0 +1,189 @@
/*
Copyright (c) 2014, Project OSRM, Dennis Luxen, others
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
Redistributions of source code must retain the above copyright notice, this list
of conditions and the following disclaimer.
Redistributions in binary form must reproduce the above copyright notice, this
list of conditions and the following disclaimer in the documentation and/or
other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "../data_structures/original_edge_data.hpp"
#include "../data_structures/query_node.hpp"
#include "../data_structures/shared_memory_vector_wrapper.hpp"
#include "../data_structures/static_rtree.hpp"
#include "../data_structures/edge_based_node.hpp"
#include "../Util/BoostFileSystemFix.h"
#include <osrm/Coordinate.h>
#include <random>
// Choosen by a fair W20 dice roll (this value is completely arbitrary)
constexpr unsigned RANDOM_SEED = 13;
constexpr int32_t WORLD_MIN_LAT = -90 * COORDINATE_PRECISION;
constexpr int32_t WORLD_MAX_LAT = 90 * COORDINATE_PRECISION;
constexpr int32_t WORLD_MIN_LON = -180 * COORDINATE_PRECISION;
constexpr int32_t WORLD_MAX_LON = 180 * COORDINATE_PRECISION;
using RTreeLeaf = EdgeBasedNode;
using FixedPointCoordinateListPtr = std::shared_ptr<std::vector<FixedPointCoordinate>>;
using BenchStaticRTree = StaticRTree<RTreeLeaf, ShM<FixedPointCoordinate, false>::vector, false>;
FixedPointCoordinateListPtr LoadCoordinates(const boost::filesystem::path &nodes_file)
{
boost::filesystem::ifstream nodes_input_stream(nodes_file, std::ios::binary);
QueryNode current_node;
unsigned coordinate_count = 0;
nodes_input_stream.read((char *)&coordinate_count, sizeof(unsigned));
auto coords = std::make_shared<std::vector<FixedPointCoordinate>>(coordinate_count);
for (unsigned i = 0; i < coordinate_count; ++i)
{
nodes_input_stream.read((char *)&current_node, sizeof(QueryNode));
coords->at(i) = FixedPointCoordinate(current_node.lat, current_node.lon);
BOOST_ASSERT((std::abs(coords->at(i).lat) >> 30) == 0);
BOOST_ASSERT((std::abs(coords->at(i).lon) >> 30) == 0);
}
nodes_input_stream.close();
return coords;
}
void Benchmark(BenchStaticRTree &rtree, unsigned num_queries)
{
std::mt19937 mt_rand(RANDOM_SEED);
std::uniform_int_distribution<> lat_udist(WORLD_MIN_LAT, WORLD_MAX_LAT);
std::uniform_int_distribution<> lon_udist(WORLD_MIN_LON, WORLD_MAX_LON);
std::vector<FixedPointCoordinate> queries;
for (unsigned i = 0; i < num_queries; i++)
{
queries.emplace_back(FixedPointCoordinate(lat_udist(mt_rand), lon_udist(mt_rand)));
}
{
const unsigned num_results = 5;
std::cout << "#### IncrementalFindPhantomNodeForCoordinate : " << num_results
<< " phantom nodes"
<< "\n";
TIMER_START(query_phantom);
std::vector<PhantomNode> phantom_node_vector;
for (const auto &q : queries)
{
phantom_node_vector.clear();
rtree.IncrementalFindPhantomNodeForCoordinate(
q, phantom_node_vector, 3, num_results);
phantom_node_vector.clear();
rtree.IncrementalFindPhantomNodeForCoordinate(
q, phantom_node_vector, 17, num_results);
}
TIMER_STOP(query_phantom);
std::cout << "Took " << TIMER_MSEC(query_phantom) << " msec for " << num_queries
<< " queries."
<< "\n";
std::cout << TIMER_MSEC(query_phantom) / ((double)num_queries) << " msec/query."
<< "\n";
std::cout << "#### LocateClosestEndPointForCoordinate"
<< "\n";
}
TIMER_START(query_endpoint);
FixedPointCoordinate result;
for (const auto &q : queries)
{
rtree.LocateClosestEndPointForCoordinate(q, result, 3);
}
TIMER_STOP(query_endpoint);
std::cout << "Took " << TIMER_MSEC(query_endpoint) << " msec for " << num_queries << " queries."
<< "\n";
std::cout << TIMER_MSEC(query_endpoint) / ((double)num_queries) << " msec/query."
<< "\n";
std::cout << "#### FindPhantomNodeForCoordinate"
<< "\n";
TIMER_START(query_node);
for (const auto &q : queries)
{
PhantomNode phantom;
rtree.FindPhantomNodeForCoordinate(q, phantom, 3);
}
TIMER_STOP(query_node);
std::cout << "Took " << TIMER_MSEC(query_node) << " msec for " << num_queries
<< " queries."
<< "\n";
std::cout << TIMER_MSEC(query_node) / ((double)num_queries) << " msec/query."
<< "\n";
{
const unsigned num_results = 1;
std::cout << "#### IncrementalFindPhantomNodeForCoordinate : " << num_results
<< " phantom nodes"
<< "\n";
TIMER_START(query_phantom);
std::vector<PhantomNode> phantom_node_vector;
for (const auto &q : queries)
{
phantom_node_vector.clear();
rtree.IncrementalFindPhantomNodeForCoordinate(
q, phantom_node_vector, 3, num_results);
phantom_node_vector.clear();
rtree.IncrementalFindPhantomNodeForCoordinate(
q, phantom_node_vector, 17, num_results);
}
TIMER_STOP(query_phantom);
std::cout << "Took " << TIMER_MSEC(query_phantom) << " msec for " << num_queries
<< " queries."
<< "\n";
std::cout << TIMER_MSEC(query_phantom) / ((double)num_queries) << " msec/query."
<< "\n";
std::cout << "#### LocateClosestEndPointForCoordinate"
<< "\n";
}
}
int main(int argc, char **argv)
{
if (argc < 4)
{
std::cout << "./rtree-bench file.ramIndex file.fileIndx file.nodes"
<< "\n";
return 1;
}
const char *ramPath = argv[1];
const char *filePath = argv[2];
const char *nodesPath = argv[3];
auto coords = LoadCoordinates(nodesPath);
BenchStaticRTree rtree(ramPath, filePath, coords);
Benchmark(rtree, 10000);
return 0;
}

View File

@ -3,8 +3,8 @@ if (EXISTS ${OLDFILE})
file(REMOVE_RECURSE ${OLDFILE})
endif()
file(MD5 ${SOURCE_DIR}/prepare.cpp MD5PREPARE)
file(MD5 ${SOURCE_DIR}/DataStructures/StaticRTree.h MD5RTREE)
file(MD5 ${SOURCE_DIR}/Util/GraphLoader.h MD5GRAPH)
file(MD5 ${SOURCE_DIR}/data_structures/static_rtree.hpp MD5RTREE)
file(MD5 ${SOURCE_DIR}/Util/graph_loader.hpp MD5GRAPH)
file(MD5 ${SOURCE_DIR}/Server/DataStructures/InternalDataFacade.h MD5OBJECTS)
CONFIGURE_FILE( ${SOURCE_DIR}/Util/FingerPrint.cpp.in ${SOURCE_DIR}/Util/FingerPrint.cpp )
CONFIGURE_FILE( ${SOURCE_DIR}/Util/finger_print.cpp.in ${SOURCE_DIR}/Util/finger_print.cpp )

View File

@ -1,6 +1,6 @@
/*
Copyright (c) 2013, Project OSRM, Dennis Luxen, others
Copyright (c) 2014, Project OSRM, Dennis Luxen, others
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
@ -25,20 +25,19 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef CONTRACTOR_H
#define CONTRACTOR_H
#ifndef CONTRACTOR_HPP
#define CONTRACTOR_HPP
#include "../DataStructures/BinaryHeap.h"
#include "../DataStructures/DeallocatingVector.h"
#include "../DataStructures/DynamicGraph.h"
#include "../DataStructures/Percent.h"
#include "../DataStructures/QueryEdge.h"
#include "../DataStructures/Range.h"
#include "../DataStructures/XORFastHash.h"
#include "../DataStructures/XORFastHashStorage.h"
#include "../data_structures/binary_heap.hpp"
#include "../data_structures/deallocating_vector.hpp"
#include "../data_structures/dynamic_graph.hpp"
#include "../data_structures/percent.hpp"
#include "../data_structures/query_edge.hpp"
#include "../data_structures/xor_fast_hash.hpp"
#include "../data_structures/xor_fast_hash_storage.hpp"
#include "../Util/integer_range.hpp"
#include "../Util/simple_logger.hpp"
#include "../Util/StringUtil.h"
#include "../Util/TimingUtil.h"
#include "../Util/timing_util.hpp"
#include "../typedefs.h"
#include <boost/assert.hpp>
@ -970,4 +969,4 @@ class Contractor
XORFastHash fast_hash;
};
#endif // CONTRACTOR_H
#endif // CONTRACTOR_HPP

View File

@ -1,6 +1,6 @@
/*
Copyright (c) 2013, Project OSRM, Dennis Luxen, others
Copyright (c) 2014, Project OSRM, Dennis Luxen, others
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
@ -25,14 +25,14 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "EdgeBasedGraphFactory.h"
#include "../Algorithms/BFSComponentExplorer.h"
#include "../DataStructures/Percent.h"
#include "../DataStructures/Range.h"
#include "edge_based_graph_factory.hpp"
#include "../algorithms/tiny_components.hpp"
#include "../data_structures/percent.hpp"
#include "../Util/compute_angle.hpp"
#include "../Util/LuaUtil.h"
#include "../Util/integer_range.hpp"
#include "../Util/lua_util.hpp"
#include "../Util/simple_logger.hpp"
#include "../Util/TimingUtil.h"
#include "../Util/timing_util.hpp"
#include <boost/assert.hpp>
@ -45,14 +45,13 @@ EdgeBasedGraphFactory::EdgeBasedGraphFactory(
std::unique_ptr<RestrictionMap> restriction_map,
std::vector<NodeID> &barrier_node_list,
std::vector<NodeID> &traffic_light_node_list,
std::vector<NodeInfo> &node_info_list,
std::vector<QueryNode> &node_info_list,
SpeedProfileProperties &speed_profile)
: speed_profile(speed_profile),
m_number_of_edge_based_nodes(std::numeric_limits<unsigned>::max()),
m_node_info_list(node_info_list), m_node_based_graph(node_based_graph),
m_restriction_map(std::move(restriction_map)), max_id(0)
m_restriction_map(std::move(restriction_map)), max_id(0), removed_node_count(0)
{
// insert into unordered sets for fast lookup
m_barrier_nodes.insert(barrier_node_list.begin(), barrier_node_list.end());
m_traffic_lights.insert(traffic_light_node_list.begin(), traffic_light_node_list.end());
@ -79,7 +78,9 @@ void EdgeBasedGraphFactory::GetEdgeBasedNodes(std::vector<EdgeBasedNode> &nodes)
}
void
EdgeBasedGraphFactory::InsertEdgeBasedNode(const NodeID node_u, const NodeID node_v, const bool belongs_to_tiny_cc)
EdgeBasedGraphFactory::InsertEdgeBasedNode(const NodeID node_u,
const NodeID node_v,
const unsigned component_id)
{
// merge edges together into one EdgeBasedNode
BOOST_ASSERT(node_u != SPECIAL_NODEID);
@ -123,7 +124,7 @@ EdgeBasedGraphFactory::InsertEdgeBasedNode(const NodeID node_u, const NodeID nod
m_geometry_compressor.GetBucketReference(e2);
BOOST_ASSERT(forward_geometry.size() == reverse_geometry.size());
BOOST_ASSERT(0 != forward_geometry.size());
const unsigned geometry_size = forward_geometry.size();
const unsigned geometry_size = static_cast<unsigned>(forward_geometry.size());
BOOST_ASSERT(geometry_size > 1);
// reconstruct bidirectional edge with individual weights and put each into the NN index
@ -181,8 +182,8 @@ EdgeBasedGraphFactory::InsertEdgeBasedNode(const NodeID node_u, const NodeID nod
forward_dist_prefix_sum[i],
reverse_dist_prefix_sum[i],
m_geometry_compressor.GetPositionForID(e1),
component_id,
i,
belongs_to_tiny_cc,
forward_data.travel_mode,
reverse_data.travel_mode);
current_edge_source_coordinate_id = current_edge_target_coordinate_id;
@ -233,8 +234,8 @@ EdgeBasedGraphFactory::InsertEdgeBasedNode(const NodeID node_u, const NodeID nod
0,
0,
SPECIAL_EDGEID,
component_id,
0,
belongs_to_tiny_cc,
forward_data.travel_mode,
reverse_data.travel_mode);
BOOST_ASSERT(!m_edge_based_node_list.back().IsCompressed());
@ -290,7 +291,6 @@ void EdgeBasedGraphFactory::CompressGeometry()
const unsigned original_number_of_edges = m_node_based_graph->GetNumberOfEdges();
Percent progress(original_number_of_nodes);
unsigned removed_node_count = 0;
for (const NodeID node_v : osrm::irange(0u, original_number_of_nodes))
{
@ -389,10 +389,14 @@ void EdgeBasedGraphFactory::CompressGeometry()
// update any involved turn restrictions
m_restriction_map->FixupStartingTurnRestriction(node_u, node_v, node_w);
m_restriction_map->FixupArrivingTurnRestriction(node_u, node_v, node_w);
m_restriction_map->FixupArrivingTurnRestriction(node_u, node_v,
node_w,
m_node_based_graph);
m_restriction_map->FixupStartingTurnRestriction(node_w, node_v, node_u);
m_restriction_map->FixupArrivingTurnRestriction(node_w, node_v, node_u);
m_restriction_map->FixupArrivingTurnRestriction(node_w,
node_v,
node_u, m_node_based_graph);
// store compressed geometry in container
m_geometry_compressor.CompressEdge(
@ -445,10 +449,9 @@ void EdgeBasedGraphFactory::RenumberEdges()
{
// renumber edge based node IDs
unsigned numbered_edges_count = 0;
for (NodeID current_node = 0; current_node < m_node_based_graph->GetNumberOfNodes();
++current_node)
for (const auto current_node : osrm::irange(0u, m_node_based_graph->GetNumberOfNodes()))
{
for (EdgeID current_edge : m_node_based_graph->GetAdjacentEdgeRange(current_node))
for (const auto current_edge : m_node_based_graph->GetAdjacentEdgeRange(current_node))
{
EdgeData &edge_data = m_node_based_graph->GetEdgeData(current_edge);
if (!edge_data.forward)
@ -471,22 +474,24 @@ void EdgeBasedGraphFactory::RenumberEdges()
*/
void EdgeBasedGraphFactory::GenerateEdgeExpandedNodes()
{
SimpleLogger().Write() << "Identifying components of the road network";
SimpleLogger().Write() << "Identifying components of the (compressed) road network";
// Run a BFS on the undirected graph and identify small components
BFSComponentExplorer<NodeBasedDynamicGraph> component_explorer(
*m_node_based_graph, *m_restriction_map, m_barrier_nodes);
TarjanSCC<NodeBasedDynamicGraph> component_explorer(
m_node_based_graph, *m_restriction_map, m_barrier_nodes);
component_explorer.run();
SimpleLogger().Write() << "identified: " << component_explorer.GetNumberOfComponents()
<< " many components";
SimpleLogger().Write() << "identified: " << component_explorer.get_number_of_components() - removed_node_count
<< " (compressed) components";
SimpleLogger().Write() << "identified " << component_explorer.get_size_one_count() - removed_node_count
<< " (compressed) SCCs of size 1";
SimpleLogger().Write() << "generating edge-expanded nodes";
Percent progress(m_node_based_graph->GetNumberOfNodes());
// loop over all edges and generate new set of nodes
for (NodeID u = 0, end = m_node_based_graph->GetNumberOfNodes(); u < end; ++u)
for (const auto u : osrm::irange(0u, m_node_based_graph->GetNumberOfNodes()))
{
BOOST_ASSERT(u != SPECIAL_NODEID);
BOOST_ASSERT(u < m_node_based_graph->GetNumberOfNodes());
@ -508,17 +513,26 @@ void EdgeBasedGraphFactory::GenerateEdgeExpandedNodes()
// Note: edges that end on barrier nodes or on a turn restriction
// may actually be in two distinct components. We choose the smallest
const unsigned size_of_component = std::min(component_explorer.GetComponentSize(u),
component_explorer.GetComponentSize(v));
const unsigned size_of_component = std::min(component_explorer.get_component_size(u),
component_explorer.get_component_size(v));
const unsigned id_of_smaller_component = [u,v,&component_explorer] {
if (component_explorer.get_component_size(u) < component_explorer.get_component_size(v))
{
return component_explorer.get_component_id(u);
}
return component_explorer.get_component_id(v);
}();
const bool component_is_tiny = (size_of_component < 1000);
if (edge_data.edgeBasedNodeID == SPECIAL_NODEID)
{
InsertEdgeBasedNode(v, u, component_is_tiny);
InsertEdgeBasedNode(v, u, (component_is_tiny ? id_of_smaller_component + 1 : 0));
}
else
{
InsertEdgeBasedNode(u, v, component_is_tiny);
InsertEdgeBasedNode(u, v, (component_is_tiny ? id_of_smaller_component + 1 : 0));
}
}
}
@ -557,7 +571,7 @@ EdgeBasedGraphFactory::GenerateEdgeExpandedEdges(const std::string &original_edg
Percent progress(m_node_based_graph->GetNumberOfNodes());
for (NodeID u = 0, end = m_node_based_graph->GetNumberOfNodes(); u < end; ++u)
for (const auto u : osrm::irange(0u, m_node_based_graph->GetNumberOfNodes()))
{
progress.printStatus(u);
for (const EdgeID e1 : m_node_based_graph->GetAdjacentEdgeRange(u))
@ -573,7 +587,7 @@ EdgeBasedGraphFactory::GenerateEdgeExpandedEdges(const std::string &original_edg
m_restriction_map->CheckForEmanatingIsOnlyTurn(u, v);
const bool is_barrier_node = (m_barrier_nodes.find(v) != m_barrier_nodes.end());
for (EdgeID e2 : m_node_based_graph->GetAdjacentEdgeRange(v))
for (const EdgeID e2 : m_node_based_graph->GetAdjacentEdgeRange(v))
{
if (!m_node_based_graph->GetEdgeData(e2).forward)
{

View File

@ -1,6 +1,6 @@
/*
Copyright (c) 2013, Project OSRM, Dennis Luxen, others
Copyright (c) 2014, Project OSRM, Dennis Luxen, others
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
@ -27,18 +27,18 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// This class constructs the edge-expanded routing graph
#ifndef EDGEBASEDGRAPHFACTORY_H_
#define EDGEBASEDGRAPHFACTORY_H_
#ifndef EDGE_BASED_GRAPH_FACTORY_HPP_
#define EDGE_BASED_GRAPH_FACTORY_HPP_
#include "geometry_compressor.hpp"
#include "../typedefs.h"
#include "../DataStructures/DeallocatingVector.h"
#include "../DataStructures/EdgeBasedNode.h"
#include "../DataStructures/OriginalEdgeData.h"
#include "../DataStructures/QueryNode.h"
#include "../DataStructures/TurnInstructions.h"
#include "../DataStructures/NodeBasedGraph.h"
#include "../DataStructures/RestrictionMap.h"
#include "GeometryCompressor.h"
#include "../data_structures/deallocating_vector.hpp"
#include "../data_structures/edge_based_node.hpp"
#include "../data_structures/original_edge_data.hpp"
#include "../data_structures/query_node.hpp"
#include "../data_structures/turn_instructions.hpp"
#include "../data_structures/node_based_graph.hpp"
#include "../data_structures/restriction_map.hpp"
#include <algorithm>
#include <iosfwd>
@ -63,7 +63,7 @@ class EdgeBasedGraphFactory
std::unique_ptr<RestrictionMap> restricion_map,
std::vector<NodeID> &barrier_node_list,
std::vector<NodeID> &traffic_light_node_list,
std::vector<NodeInfo> &m_node_info_list,
std::vector<QueryNode> &node_info_list,
SpeedProfileProperties &speed_profile);
void Run(const std::string &original_edge_data_filename,
@ -97,7 +97,7 @@ class EdgeBasedGraphFactory
unsigned m_number_of_edge_based_nodes;
std::vector<NodeInfo> m_node_info_list;
std::vector<QueryNode> m_node_info_list;
std::vector<EdgeBasedNode> m_edge_based_node_list;
DeallocatingVector<EdgeBasedEdge> m_edge_based_edge_list;
@ -115,12 +115,14 @@ class EdgeBasedGraphFactory
void GenerateEdgeExpandedEdges(const std::string &original_edge_data_filename,
lua_State *lua_state);
void InsertEdgeBasedNode(const NodeID u, const NodeID v, const bool belongsToTinyComponent);
void InsertEdgeBasedNode(const NodeID u, const NodeID v, const unsigned component_id);
void FlushVectorToStream(std::ofstream &edge_data_file,
std::vector<OriginalEdgeData> &original_edge_data_vector) const;
NodeID max_id;
std::size_t removed_node_count;
};
#endif /* EDGEBASEDGRAPHFACTORY_H_ */
#endif /* EDGE_BASED_GRAPH_FACTORY_HPP_ */

View File

@ -1,6 +1,6 @@
/*
Copyright (c) 2013, Project OSRM, Dennis Luxen, others
Copyright (c) 2014, Project OSRM, Dennis Luxen, others
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
@ -25,7 +25,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "GeometryCompressor.h"
#include "geometry_compressor.hpp"
#include "../Util/simple_logger.hpp"
#include <boost/assert.hpp>

View File

@ -1,6 +1,6 @@
/*
Copyright (c) 2013, Project OSRM, Dennis Luxen, others
Copyright (c) 2014, Project OSRM, Dennis Luxen, others
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
@ -25,8 +25,8 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef GEOMETRY_COMPRESSOR_H
#define GEOMETRY_COMPRESSOR_H
#ifndef GEOMETRY_COMPRESSOR_HPP_
#define GEOMETRY_COMPRESSOR_HPP_
#include "../typedefs.h"
@ -64,4 +64,4 @@ class GeometryCompressor
std::unordered_map<EdgeID, unsigned> m_edge_id_to_list_index_map;
};
#endif // GEOMETRY_COMPRESSOR_H
#endif // GEOMETRY_COMPRESSOR_HPP_

View File

@ -1,6 +1,6 @@
/*
Copyright (c) 2013, Project OSRM, Dennis Luxen, others
Copyright (c) 2015, Project OSRM, Dennis Luxen, others
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
@ -25,24 +25,24 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "Prepare.h"
#include "processing_chain.hpp"
#include "Contractor.h"
#include "contractor.hpp"
#include "../Algorithms/IteratorBasedCRC32.h"
#include "../DataStructures/BinaryHeap.h"
#include "../DataStructures/DeallocatingVector.h"
#include "../DataStructures/Range.h"
#include "../DataStructures/StaticRTree.h"
#include "../DataStructures/RestrictionMap.h"
#include "../algorithms/crc32_processor.hpp"
#include "../data_structures/deallocating_vector.hpp"
#include "../data_structures/static_rtree.hpp"
#include "../data_structures/restriction_map.hpp"
#include "../Util/GitDescription.h"
#include "../Util/LuaUtil.h"
#include "../Util/git_sha.hpp"
#include "../Util/graph_loader.hpp"
#include "../Util/integer_range.hpp"
#include "../Util/lua_util.hpp"
#include "../Util/make_unique.hpp"
#include "../Util/OSRMException.h"
#include "../Util/osrm_exception.hpp"
#include "../Util/simple_logger.hpp"
#include "../Util/StringUtil.h"
#include "../Util/TimingUtil.h"
#include "../Util/string_util.hpp"
#include "../Util/timing_util.hpp"
#include "../typedefs.h"
#include <boost/filesystem/fstream.hpp>
@ -394,6 +394,13 @@ bool Prepare::ParseArguments(int argc, char *argv[])
.run(),
option_variables);
const auto& temp_config_path = option_variables["config"].as<boost::filesystem::path>();
if (boost::filesystem::is_regular_file(temp_config_path))
{
boost::program_options::store(boost::program_options::parse_config_file<char>(temp_config_path.string().c_str(), cmdline_options, true),
option_variables);
}
if (option_variables.count("version"))
{
SimpleLogger().Write() << g_GIT_DESCRIPTION;
@ -502,8 +509,7 @@ Prepare::BuildEdgeExpandedGraph(lua_State *lua_state,
SimpleLogger().Write() << "Generating edge-expanded graph representation";
std::shared_ptr<NodeBasedDynamicGraph> node_based_graph =
NodeBasedDynamicGraphFromImportEdges(number_of_node_based_nodes, edge_list);
std::unique_ptr<RestrictionMap> restriction_map =
std::unique_ptr<RestrictionMap>(new RestrictionMap(node_based_graph, restriction_list));
std::unique_ptr<RestrictionMap> restriction_map = osrm::make_unique<RestrictionMap>(restriction_list);
std::shared_ptr<EdgeBasedGraphFactory> edge_based_graph_factory =
std::make_shared<EdgeBasedGraphFactory>(node_based_graph,
std::move(restriction_map),
@ -553,7 +559,7 @@ void Prepare::WriteNodeMapping()
if (size_of_mapping > 0)
{
node_stream.write((char *)&(internal_to_external_node_map[0]),
size_of_mapping * sizeof(NodeInfo));
size_of_mapping * sizeof(QueryNode));
}
node_stream.close();
internal_to_external_node_map.clear();

View File

@ -1,15 +1,43 @@
#ifndef PREPARE_H
#define PREPARE_H
/*
#include "EdgeBasedGraphFactory.h"
#include "../DataStructures/QueryEdge.h"
#include "../DataStructures/StaticGraph.h"
#include "../Util/GraphLoader.h"
Copyright (c) 2014, Project OSRM, Dennis Luxen, others
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
Redistributions of source code must retain the above copyright notice, this list
of conditions and the following disclaimer.
Redistributions in binary form must reproduce the above copyright notice, this
list of conditions and the following disclaimer in the documentation and/or
other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef PROCESSING_CHAIN_HPP
#define PROCESSING_CHAIN_HPP
#include "edge_based_graph_factory.hpp"
#include "../data_structures/query_edge.hpp"
#include "../data_structures/static_graph.hpp"
class FingerPrint;
struct EdgeBasedNode;
struct lua_State;
#include <boost/filesystem.hpp>
#include <luabind/luabind.hpp>
#include <vector>
/**
@ -42,7 +70,7 @@ class Prepare
void BuildRTree(std::vector<EdgeBasedNode> &node_based_edge_list);
private:
std::vector<NodeInfo> internal_to_external_node_map;
std::vector<QueryNode> internal_to_external_node_map;
std::vector<TurnRestriction> restriction_list;
std::vector<NodeID> barrier_node_list;
std::vector<NodeID> traffic_light_list;
@ -64,4 +92,4 @@ class Prepare
std::string rtree_leafs_path;
};
#endif // PREPARE_H
#endif // PROCESSING_CHAIN_HPP

View File

@ -30,7 +30,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef NDEBUG
#include "../Util/simple_logger.hpp"
#endif
#include "../Util/StringUtil.h"
#include "../Util/string_util.hpp"
#include <boost/assert.hpp>
@ -72,7 +72,7 @@ bool FixedPointCoordinate::isSet() const
{
return (std::numeric_limits<int>::min() != lat) && (std::numeric_limits<int>::min() != lon);
}
bool FixedPointCoordinate::isValid() const
bool FixedPointCoordinate::is_valid() const
{
if (lat > 90 * COORDINATE_PRECISION || lat < -90 * COORDINATE_PRECISION ||
lon > 180 * COORDINATE_PRECISION || lon < -180 * COORDINATE_PRECISION)
@ -246,7 +246,7 @@ FixedPointCoordinate::ComputePerpendicularDistance(const FixedPointCoordinate &s
nearest_location.lon = static_cast<int>(q * COORDINATE_PRECISION);
}
BOOST_ASSERT(nearest_location.isValid());
BOOST_ASSERT(nearest_location.is_valid());
return FixedPointCoordinate::ApproximateEuclideanDistance(point, nearest_location);
}
@ -256,7 +256,7 @@ float FixedPointCoordinate::ComputePerpendicularDistance(const FixedPointCoordin
FixedPointCoordinate &nearest_location,
float &ratio)
{
BOOST_ASSERT(query_location.isValid());
BOOST_ASSERT(query_location.is_valid());
// initialize values
const double x = lat2y(query_location.lat / COORDINATE_PRECISION);
@ -319,7 +319,7 @@ float FixedPointCoordinate::ComputePerpendicularDistance(const FixedPointCoordin
nearest_location.lat = static_cast<int>(y2lat(p) * COORDINATE_PRECISION);
nearest_location.lon = static_cast<int>(q * COORDINATE_PRECISION);
}
BOOST_ASSERT(nearest_location.isValid());
BOOST_ASSERT(nearest_location.is_valid());
const float approximate_distance =
FixedPointCoordinate::ApproximateEuclideanDistance(query_location, nearest_location);

View File

@ -1,6 +1,6 @@
/*
Copyright (c) 2013, Project OSRM, Dennis Luxen, others
Copyright (c) 2014, Project OSRM, Dennis Luxen, others
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,

View File

@ -1,6 +1,6 @@
/*
Copyright (c) 2013, Project OSRM, Dennis Luxen, others
Copyright (c) 2014, Project OSRM, Dennis Luxen, others
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
@ -25,8 +25,8 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef CONCURRENT_QUEUE_H
#define CONCURRENT_QUEUE_H
#ifndef CONCURRENT_QUEUE_HPP
#define CONCURRENT_QUEUE_HPP
#include <boost/circular_buffer.hpp>
#include <condition_variable>
@ -80,4 +80,4 @@ template <typename Data> class ConcurrentQueue
std::condition_variable m_not_full;
};
#endif // CONCURRENT_QUEUE_H
#endif // CONCURRENT_QUEUE_HPP

View File

@ -28,7 +28,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef DEALLOCATINGVECTOR_H_
#define DEALLOCATINGVECTOR_H_
#include "Range.h"
#include "../Util/integer_range.hpp"
#include <boost/iterator/iterator_facade.hpp>

View File

@ -1,6 +1,6 @@
/*
Copyright (c) 2013, Project OSRM, Dennis Luxen, others
Copyright (c) 2014, Project OSRM, Dennis Luxen, others
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
@ -25,11 +25,11 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef DYNAMICGRAPH_H
#define DYNAMICGRAPH_H
#ifndef DYNAMICGRAPH_HPP
#define DYNAMICGRAPH_HPP
#include "DeallocatingVector.h"
#include "Range.h"
#include "deallocating_vector.hpp"
#include "../Util/integer_range.hpp"
#include <boost/assert.hpp>
@ -100,7 +100,7 @@ template <typename EdgeDataT> class DynamicGraph
position += node_list[node].edges;
}
node_list.back().firstEdge = position;
edge_list.reserve((std::size_t)edge_list.size() * 1.1);
edge_list.reserve(static_cast<std::size_t>(edge_list.size() * 1.1));
edge_list.resize(position);
edge = 0;
for (const auto node : osrm::irange(0u, number_of_nodes))
@ -292,4 +292,4 @@ template <typename EdgeDataT> class DynamicGraph
DeallocatingVector<Edge> edge_list;
};
#endif // DYNAMICGRAPH_H
#endif // DYNAMICGRAPH_HPP

View File

@ -1,7 +1,34 @@
#ifndef EDGE_BASED_NODE_H
#define EDGE_BASED_NODE_H
/*
#include "../DataStructures/TravelMode.h"
Copyright (c) 2014, Project OSRM, Dennis Luxen, others
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
Redistributions of source code must retain the above copyright notice, this list
of conditions and the following disclaimer.
Redistributions in binary form must reproduce the above copyright notice, this
list of conditions and the following disclaimer in the documentation and/or
other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef EDGE_BASED_NODE_HPP
#define EDGE_BASED_NODE_HPP
#include "../data_structures/travel_mode.hpp"
#include "../typedefs.h"
#include <osrm/Coordinate.h>
@ -12,7 +39,6 @@
struct EdgeBasedNode
{
EdgeBasedNode() :
forward_edge_based_node_id(SPECIAL_NODEID),
reverse_edge_based_node_id(SPECIAL_NODEID),
@ -24,8 +50,8 @@ struct EdgeBasedNode
forward_offset(0),
reverse_offset(0),
packed_geometry_id(SPECIAL_EDGEID),
component_id(-1),
fwd_segment_position( std::numeric_limits<unsigned short>::max() ),
is_in_tiny_cc(false),
forward_travel_mode(TRAVEL_MODE_INACCESSIBLE),
backward_travel_mode(TRAVEL_MODE_INACCESSIBLE)
{ }
@ -41,8 +67,8 @@ struct EdgeBasedNode
int forward_offset,
int reverse_offset,
unsigned packed_geometry_id,
unsigned component_id,
unsigned short fwd_segment_position,
bool belongs_to_tiny_component,
TravelMode forward_travel_mode,
TravelMode backward_travel_mode
) :
@ -56,8 +82,8 @@ struct EdgeBasedNode
forward_offset(forward_offset),
reverse_offset(reverse_offset),
packed_geometry_id(packed_geometry_id),
component_id(component_id),
fwd_segment_position(fwd_segment_position),
is_in_tiny_cc(belongs_to_tiny_component),
forward_travel_mode(forward_travel_mode),
backward_travel_mode(backward_travel_mode)
{
@ -79,6 +105,11 @@ struct EdgeBasedNode
return packed_geometry_id != SPECIAL_EDGEID;
}
bool is_in_tiny_cc() const
{
return 0 != component_id;
}
NodeID forward_edge_based_node_id; // needed for edge-expanded graph
NodeID reverse_edge_based_node_id; // needed for edge-expanded graph
NodeID u; // indices into the coordinates array
@ -89,10 +120,10 @@ struct EdgeBasedNode
int forward_offset; // prefix sum of the weight up the edge TODO: short must suffice
int reverse_offset; // prefix sum of the weight from the edge TODO: short must suffice
unsigned packed_geometry_id; // if set, then the edge represents a packed geometry
unsigned component_id;
unsigned short fwd_segment_position; // segment id in a compressed geometry
bool is_in_tiny_cc;
TravelMode forward_travel_mode : 4;
TravelMode backward_travel_mode : 4;
};
#endif //EDGE_BASED_NODE_H
#endif //EDGE_BASED_NODE_HPP

View File

@ -25,19 +25,17 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "ImportNode.h"
#include "external_memory_node.hpp"
#include <limits>
ExternalMemoryNode::ExternalMemoryNode(
int lat, int lon, unsigned int node_id, bool bollard, bool traffic_light)
: NodeInfo(lat, lon, node_id), bollard(bollard), trafficLight(traffic_light)
int lat, int lon, unsigned int node_id, bool barrier, bool traffic_lights)
: QueryNode(lat, lon, node_id), barrier(barrier), traffic_lights(traffic_lights)
{
}
ExternalMemoryNode::ExternalMemoryNode() : bollard(false), trafficLight(false)
{
}
ExternalMemoryNode::ExternalMemoryNode() : barrier(false), traffic_lights(false) {}
ExternalMemoryNode ExternalMemoryNode::min_value()
{
@ -53,12 +51,18 @@ ExternalMemoryNode ExternalMemoryNode::max_value()
false);
}
void ImportNode::Clear()
bool ExternalMemoryNodeSTXXLCompare::operator()(const ExternalMemoryNode &left,
const ExternalMemoryNode &right) const
{
keyVals.Clear();
lat = 0;
lon = 0;
node_id = 0;
bollard = false;
trafficLight = false;
return left.node_id < right.node_id;
}
ExternalMemoryNodeSTXXLCompare::value_type ExternalMemoryNodeSTXXLCompare::max_value()
{
return ExternalMemoryNode::max_value();
}
ExternalMemoryNodeSTXXLCompare::value_type ExternalMemoryNodeSTXXLCompare::min_value()
{
return ExternalMemoryNode::min_value();
}

View File

@ -1,6 +1,6 @@
/*
Copyright (c) 2013, Project OSRM, Dennis Luxen, others
Copyright (c) 2014, Project OSRM, Dennis Luxen, others
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
@ -25,17 +25,16 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef IMPORTNODE_H_
#define IMPORTNODE_H_
#ifndef EXTERNAL_MEMORY_NODE_HPP_
#define EXTERNAL_MEMORY_NODE_HPP_
#include "QueryNode.h"
#include "../DataStructures/HashTable.h"
#include "query_node.hpp"
#include <string>
struct ExternalMemoryNode : NodeInfo
struct ExternalMemoryNode : QueryNode
{
ExternalMemoryNode(int lat, int lon, unsigned int id, bool bollard, bool traffic_light);
ExternalMemoryNode(int lat, int lon, NodeID id, bool barrier, bool traffic_light);
ExternalMemoryNode();
@ -43,15 +42,16 @@ struct ExternalMemoryNode : NodeInfo
static ExternalMemoryNode max_value();
bool bollard;
bool trafficLight;
bool barrier;
bool traffic_lights;
};
struct ImportNode : public ExternalMemoryNode
struct ExternalMemoryNodeSTXXLCompare
{
HashTable<std::string, std::string> keyVals;
inline void Clear();
using value_type = ExternalMemoryNode;
bool operator()(const ExternalMemoryNode &left, const ExternalMemoryNode &right) const;
value_type max_value();
value_type min_value();
};
#endif /* IMPORTNODE_H_ */
#endif /* EXTERNAL_MEMORY_NODE_HPP_ */

View File

@ -1,6 +1,6 @@
/*
Copyright (c) 2013, Project OSRM, Dennis Luxen, others
Copyright (c) 2014, Project OSRM, Dennis Luxen, others
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
@ -25,8 +25,8 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef OSRM_FIXED_POINT_NUMBER_H
#define OSRM_FIXED_POINT_NUMBER_H
#ifndef FIXED_POINT_NUMBER_HPP
#define FIXED_POINT_NUMBER_HPP
#include <cmath>
#include <cstdint>
@ -213,4 +213,4 @@ class FixedPointNumber
static_assert(4 == sizeof(FixedPointNumber<1>), "FP19 has wrong size != 4");
}
#endif // OSRM_FIXED_POINT_NUMBER_H
#endif // FIXED_POINT_NUMBER_HPP

View File

@ -1,6 +1,6 @@
/*
Copyright (c) 2013, Project OSRM, Dennis Luxen, others
Copyright (c) 2014, Project OSRM, Dennis Luxen, others
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
@ -25,7 +25,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "HilbertValue.h"
#include "hilbert_value.hpp"
#include <osrm/Coordinate.h>

View File

@ -1,6 +1,6 @@
/*
Copyright (c) 2013, Project OSRM, Dennis Luxen, others
Copyright (c) 2014, Project OSRM, Dennis Luxen, others
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
@ -25,8 +25,8 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef HILBERTVALUE_H_
#define HILBERTVALUE_H_
#ifndef HILBERT_VALUE_HPP
#define HILBERT_VALUE_HPP
#include <cstdint>
@ -46,4 +46,4 @@ class HilbertCode
inline void TransposeCoordinate(uint32_t *X) const;
};
#endif /* HILBERTVALUE_H_ */
#endif /* HILBERT_VALUE_HPP */

View File

@ -25,7 +25,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "ImportEdge.h"
#include "import_edge.hpp"
#include <boost/assert.hpp>

Some files were not shown because too many files have changed in this diff Show More