Add ability to debug routing graph visually by dumping

annotated GeoJSON during processing.
This commit is contained in:
Daniel Patterson 2015-10-14 15:08:22 -07:00
parent 673bf356e4
commit b9a4c322a7
15 changed files with 341 additions and 41 deletions

View File

@ -30,6 +30,7 @@ if(WIN32 AND MSVC_VERSION LESS 1800)
endif() endif()
option(ENABLE_JSON_LOGGING "Adds additional JSON debug logging to the response" OFF) option(ENABLE_JSON_LOGGING "Adds additional JSON debug logging to the response" OFF)
option(DEBUG_GEOMETRY "Enables an option to dump GeoJSON of the final routing graph" OFF)
option(BUILD_TOOLS "Build OSRM tools" OFF) option(BUILD_TOOLS "Build OSRM tools" OFF)
include_directories(${CMAKE_CURRENT_SOURCE_DIR}) include_directories(${CMAKE_CURRENT_SOURCE_DIR})
@ -332,6 +333,11 @@ if (ENABLE_JSON_LOGGING)
add_definitions(-DENABLE_JSON_LOGGING) add_definitions(-DENABLE_JSON_LOGGING)
endif() endif()
if (DEBUG_GEOMETRY)
message(STATUS "Enabling final edge weight GeoJSON output option")
add_definitions(-DDEBUG_GEOMETRY)
endif()
if(BUILD_TOOLS) if(BUILD_TOOLS)
message(STATUS "Activating OSRM internal tools") message(STATUS "Activating OSRM internal tools")
find_package(GDAL) find_package(GDAL)

View File

@ -6,6 +6,8 @@ ECHO ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ %~f0 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
SET PROJECT_DIR=%CD% SET PROJECT_DIR=%CD%
ECHO PROJECT_DIR^: %PROJECT_DIR% ECHO PROJECT_DIR^: %PROJECT_DIR%
ECHO NUMBER_OF_PROCESSORS^: %NUMBER_OF_PROCESSORS%
ECHO cmake^: && cmake --version
ECHO activating VS command prompt ... ECHO activating VS command prompt ...
SET PATH=C:\Program Files (x86)\MSBuild\14.0\Bin;%PATH% SET PATH=C:\Program Files (x86)\MSBuild\14.0\Bin;%PATH%
@ -50,7 +52,7 @@ set TBB_ARCH_PLATFORM=intel64/vc14
ECHO calling cmake .... ECHO calling cmake ....
cmake .. ^ cmake .. ^
-G "Visual Studio 14 Win64" ^ -G "Visual Studio 14 2015 Win64" ^
-DBOOST_ROOT=%BOOST_ROOT% ^ -DBOOST_ROOT=%BOOST_ROOT% ^
-DBoost_ADDITIONAL_VERSIONS=1.58 ^ -DBoost_ADDITIONAL_VERSIONS=1.58 ^
-DBoost_USE_MULTITHREADED=ON ^ -DBoost_USE_MULTITHREADED=ON ^

View File

@ -11,7 +11,8 @@ SET CONFIGURATION=Release
FOR /F "tokens=*" %%i in ('git rev-parse --abbrev-ref HEAD') do SET APPVEYOR_REPO_BRANCH=%%i FOR /F "tokens=*" %%i in ('git rev-parse --abbrev-ref HEAD') do SET APPVEYOR_REPO_BRANCH=%%i
ECHO APPVEYOR_REPO_BRANCH^: %APPVEYOR_REPO_BRANCH% ECHO APPVEYOR_REPO_BRANCH^: %APPVEYOR_REPO_BRANCH%
SET PATH=C:\mb\windows-builds-64\tmp-bin\cmake-3.1.0-win32-x86\bin;%PATH% ::SET PATH=C:\mb\windows-builds-64\tmp-bin\cmake-3.1.0-win32-x86\bin;%PATH%
SET PATH=C:\mb\windows-builds-64\tmp-bin\cmake-3.4.0-win32-x86\bin;%PATH%
SET PATH=C:\Program Files\7-Zip;%PATH% SET PATH=C:\Program Files\7-Zip;%PATH%
powershell Set-ExecutionPolicy -Scope CurrentUser -ExecutionPolicy Unrestricted -Force powershell Set-ExecutionPolicy -Scope CurrentUser -ExecutionPolicy Unrestricted -Force

View File

@ -55,6 +55,14 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
class Contractor class Contractor
{ {
public:
struct RemainingNodeData
{
RemainingNodeData() : id(0), is_independent(false) {}
NodeID id : 31;
bool is_independent : 1;
};
private: private:
struct ContractorEdgeData struct ContractorEdgeData
@ -127,13 +135,6 @@ class Contractor
} }
}; };
struct RemainingNodeData
{
RemainingNodeData() : id(0), is_independent(false) {}
NodeID id : 31;
bool is_independent : 1;
};
struct ThreadDataContainer struct ThreadDataContainer
{ {
explicit ThreadDataContainer(int number_of_nodes) : number_of_nodes(number_of_nodes) {} explicit ThreadDataContainer(int number_of_nodes) : number_of_nodes(number_of_nodes) {}

View File

@ -56,13 +56,20 @@ ContractorOptions::ParseArguments(int argc, char *argv[], ContractorConfig &cont
boost::program_options::value<unsigned int>(&contractor_config.requested_num_threads) boost::program_options::value<unsigned int>(&contractor_config.requested_num_threads)
->default_value(tbb::task_scheduler_init::default_num_threads()), ->default_value(tbb::task_scheduler_init::default_num_threads()),
"Number of threads to use")( "Number of threads to use")(
"core,k", "core,k", boost::program_options::value<double>(&contractor_config.core_factor)
boost::program_options::value<double>(&contractor_config.core_factor)->default_value(1.0), ->default_value(1.0),"Percentage of the graph (in vertices) to contract [0..1]")(
"Percentage of the graph (in vertices) to contract [0.1]")( "segment-speed-file", boost::program_options::value<std::string>(&contractor_config.segment_speed_lookup_path),
"Lookup file containing nodeA,nodeB,speed data to adjust edge weights")(
"level-cache,o", "level-cache,o",
boost::program_options::value<bool>(&contractor_config.use_cached_priority)->default_value(false), boost::program_options::value<bool>(&contractor_config.use_cached_priority)->default_value(false),
"Use .level file to retain the contaction level for each node from the last run."); "Use .level file to retain the contaction level for each node from the last run.");
#ifdef DEBUG_GEOMETRY
config_options.add_options()(
"debug-geometry", boost::program_options::value<std::string>(&contractor_config.debug_geometry_path)
,"Write out edge-weight debugging geometry data in GeoJSON format to this file");
#endif
// hidden options, will be allowed both on command line and in config file, but will not be // hidden options, will be allowed both on command line and in config file, but will not be
// shown to the user // shown to the user
boost::program_options::options_description hidden_options("Hidden options"); boost::program_options::options_description hidden_options("Hidden options");

View File

@ -66,6 +66,9 @@ struct ContractorConfig
std::string segment_speed_lookup_path; std::string segment_speed_lookup_path;
#ifdef DEBUG_GEOMETRY
std::string debug_geometry_path;
#endif
}; };
struct ContractorOptions struct ContractorOptions

View File

@ -55,6 +55,8 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <thread> #include <thread>
#include <vector> #include <vector>
#include "../util/debug_geometry.hpp"
Prepare::~Prepare() {} Prepare::~Prepare() {}
int Prepare::Run() int Prepare::Run()
@ -95,7 +97,8 @@ int Prepare::Run()
ReadNodeLevels(node_levels); ReadNodeLevels(node_levels);
} }
DeallocatingVector<QueryEdge> contracted_edge_list; DeallocatingVector<QueryEdge> contracted_edge_list;
ContractGraph(max_edge_id, edge_based_edge_list, contracted_edge_list, is_core_node, node_levels); ContractGraph(max_edge_id, edge_based_edge_list, contracted_edge_list, is_core_node,
node_levels);
TIMER_STOP(contraction); TIMER_STOP(contraction);
SimpleLogger().Write() << "Contraction took " << TIMER_SEC(contraction) << " sec"; SimpleLogger().Write() << "Contraction took " << TIMER_SEC(contraction) << " sec";
@ -186,12 +189,14 @@ std::size_t Prepare::LoadEdgeExpandedGraph(std::string const &edge_based_graph_f
} }
} }
DEBUG_GEOMETRY_START(config);
// TODO: can we read this in bulk? DeallocatingVector isn't necessarily // TODO: can we read this in bulk? DeallocatingVector isn't necessarily
// all stored contiguously // all stored contiguously
for (; number_of_edges > 0; --number_of_edges) for (; number_of_edges > 0; --number_of_edges)
{ {
EdgeBasedEdge inbuffer; EdgeBasedEdge inbuffer;
input_stream.read((char *)&inbuffer, sizeof(EdgeBasedEdge)); input_stream.read((char *) &inbuffer, sizeof(EdgeBasedEdge));
if (update_edge_weights) if (update_edge_weights)
{ {
@ -232,11 +237,23 @@ std::size_t Prepare::LoadEdgeExpandedGraph(std::string const &edge_based_graph_f
std::max(1, static_cast<int>(std::floor( std::max(1, static_cast<int>(std::floor(
(segment_length * 10.) / (speed_iter->second / 3.6) + .5))); (segment_length * 10.) / (speed_iter->second / 3.6) + .5)));
new_weight += new_segment_weight; new_weight += new_segment_weight;
DEBUG_GEOMETRY_EDGE(
new_segment_weight,
segment_length,
previous_osm_node_id,
this_osm_node_id);
} }
else else
{ {
// If no lookup found, use the original weight value for this segment // If no lookup found, use the original weight value for this segment
new_weight += segment_weight; new_weight += segment_weight;
DEBUG_GEOMETRY_EDGE(
segment_weight,
segment_length,
previous_osm_node_id,
this_osm_node_id);
} }
previous_osm_node_id = this_osm_node_id; previous_osm_node_id = this_osm_node_id;
@ -247,33 +264,31 @@ std::size_t Prepare::LoadEdgeExpandedGraph(std::string const &edge_based_graph_f
edge_based_edge_list.emplace_back(std::move(inbuffer)); edge_based_edge_list.emplace_back(std::move(inbuffer));
} }
DEBUG_GEOMETRY_STOP();
SimpleLogger().Write() << "Done reading edges"; SimpleLogger().Write() << "Done reading edges";
return max_edge_id; return max_edge_id;
} }
void Prepare::ReadNodeLevels(std::vector<float> &node_levels) const void Prepare::ReadNodeLevels(std::vector<float> &node_levels) const
{ {
boost::filesystem::ifstream order_input_stream(config.level_output_path, boost::filesystem::ifstream order_input_stream(config.level_output_path, std::ios::binary);
std::ios::binary);
unsigned level_size; unsigned level_size;
order_input_stream.read((char *)&level_size, sizeof(unsigned)); order_input_stream.read((char *)&level_size, sizeof(unsigned));
node_levels.resize(level_size); node_levels.resize(level_size);
order_input_stream.read((char *)node_levels.data(), order_input_stream.read((char *)node_levels.data(), sizeof(float) * node_levels.size());
sizeof(float) * node_levels.size());
} }
void Prepare::WriteNodeLevels(std::vector<float> &&in_node_levels) const void Prepare::WriteNodeLevels(std::vector<float> &&in_node_levels) const
{ {
std::vector<float> node_levels(std::move(in_node_levels)); std::vector<float> node_levels(std::move(in_node_levels));
boost::filesystem::ofstream order_output_stream(config.level_output_path, boost::filesystem::ofstream order_output_stream(config.level_output_path, std::ios::binary);
std::ios::binary);
unsigned level_size = node_levels.size(); unsigned level_size = node_levels.size();
order_output_stream.write((char *)&level_size, sizeof(unsigned)); order_output_stream.write((char *)&level_size, sizeof(unsigned));
order_output_stream.write((char *)node_levels.data(), order_output_stream.write((char *)node_levels.data(), sizeof(float) * node_levels.size());
sizeof(float) * node_levels.size());
} }
void Prepare::WriteCoreNodeMarker(std::vector<bool> &&in_is_core_node) const void Prepare::WriteCoreNodeMarker(std::vector<bool> &&in_is_core_node) const

View File

@ -28,6 +28,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef PROCESSING_CHAIN_HPP #ifndef PROCESSING_CHAIN_HPP
#define PROCESSING_CHAIN_HPP #define PROCESSING_CHAIN_HPP
#include "contractor.hpp"
#include "contractor_options.hpp" #include "contractor_options.hpp"
#include "../data_structures/query_edge.hpp" #include "../data_structures/query_edge.hpp"
#include "../data_structures/static_graph.hpp" #include "../data_structures/static_graph.hpp"

View File

@ -35,6 +35,8 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "../util/timing_util.hpp" #include "../util/timing_util.hpp"
#include "../util/osrm_exception.hpp" #include "../util/osrm_exception.hpp"
#include "../util/debug_geometry.hpp"
#include <boost/assert.hpp> #include <boost/assert.hpp>
#include <fstream> #include <fstream>
@ -222,12 +224,20 @@ void EdgeBasedGraphFactory::FlushVectorToStream(
original_edge_data_vector.clear(); original_edge_data_vector.clear();
} }
#ifdef DEBUG_GEOMETRY
void EdgeBasedGraphFactory::Run(const std::string &original_edge_data_filename, void EdgeBasedGraphFactory::Run(const std::string &original_edge_data_filename,
lua_State *lua_state, lua_State *lua_state,
const std::string &edge_segment_lookup_filename, const std::string &edge_segment_lookup_filename,
const std::string &edge_penalty_filename, const std::string &edge_penalty_filename,
const bool generate_edge_lookup const bool generate_edge_lookup,
) const std::string &debug_turns_path)
#else
void EdgeBasedGraphFactory::Run(const std::string &original_edge_data_filename,
lua_State *lua_state,
const std::string &edge_segment_lookup_filename,
const std::string &edge_penalty_filename,
const bool generate_edge_lookup)
#endif
{ {
TIMER_START(renumber); TIMER_START(renumber);
m_max_edge_id = RenumberEdges() - 1; m_max_edge_id = RenumberEdges() - 1;
@ -238,9 +248,16 @@ void EdgeBasedGraphFactory::Run(const std::string &original_edge_data_filename,
TIMER_STOP(generate_nodes); TIMER_STOP(generate_nodes);
TIMER_START(generate_edges); TIMER_START(generate_edges);
#ifdef DEBUG_GEOMETRY
GenerateEdgeExpandedEdges(original_edge_data_filename, lua_state, GenerateEdgeExpandedEdges(original_edge_data_filename, lua_state,
edge_segment_lookup_filename,edge_penalty_filename, generate_edge_lookup edge_segment_lookup_filename,edge_penalty_filename,
); generate_edge_lookup, debug_turns_path);
#else
GenerateEdgeExpandedEdges(original_edge_data_filename, lua_state,
edge_segment_lookup_filename,edge_penalty_filename,
generate_edge_lookup);
#endif
TIMER_STOP(generate_edges); TIMER_STOP(generate_edges);
SimpleLogger().Write() << "Timing statistics for edge-expanded graph:"; SimpleLogger().Write() << "Timing statistics for edge-expanded graph:";
@ -324,12 +341,20 @@ void EdgeBasedGraphFactory::GenerateEdgeExpandedNodes()
} }
/// Actually it also generates OriginalEdgeData and serializes them... /// Actually it also generates OriginalEdgeData and serializes them...
#ifdef DEBUG_GEOMETRY
void EdgeBasedGraphFactory::GenerateEdgeExpandedEdges( void EdgeBasedGraphFactory::GenerateEdgeExpandedEdges(
const std::string &original_edge_data_filename, lua_State *lua_state, const std::string &original_edge_data_filename, lua_State *lua_state,
const std::string &edge_segment_lookup_filename, const std::string &edge_segment_lookup_filename,
const std::string &edge_fixed_penalties_filename, const std::string &edge_fixed_penalties_filename,
const bool generate_edge_lookup const bool generate_edge_lookup,
) const std::string &debug_turns_path)
#else
void EdgeBasedGraphFactory::GenerateEdgeExpandedEdges(
const std::string &original_edge_data_filename, lua_State *lua_state,
const std::string &edge_segment_lookup_filename,
const std::string &edge_fixed_penalties_filename,
const bool generate_edge_lookup)
#endif
{ {
SimpleLogger().Write() << "generating edge-expanded edges"; SimpleLogger().Write() << "generating edge-expanded edges";
@ -362,9 +387,13 @@ void EdgeBasedGraphFactory::GenerateEdgeExpandedEdges(
Percent progress(m_node_based_graph->GetNumberOfNodes()); Percent progress(m_node_based_graph->GetNumberOfNodes());
#ifdef DEBUG_GEOMETRY
DEBUG_TURNS_START(debug_turns_path);
#endif
for (const auto node_u : osrm::irange(0u, m_node_based_graph->GetNumberOfNodes())) for (const auto node_u : osrm::irange(0u, m_node_based_graph->GetNumberOfNodes()))
{ {
progress.printStatus(node_u); //progress.printStatus(node_u);
for (const EdgeID e1 : m_node_based_graph->GetAdjacentEdgeRange(node_u)) for (const EdgeID e1 : m_node_based_graph->GetAdjacentEdgeRange(node_u))
{ {
if (m_node_based_graph->GetEdgeData(e1).reversed) if (m_node_based_graph->GetEdgeData(e1).reversed)
@ -435,6 +464,8 @@ void EdgeBasedGraphFactory::GenerateEdgeExpandedEdges(
if (m_traffic_lights.find(node_v) != m_traffic_lights.end()) if (m_traffic_lights.find(node_v) != m_traffic_lights.end())
{ {
distance += speed_profile.traffic_signal_penalty; distance += speed_profile.traffic_signal_penalty;
DEBUG_SIGNAL(node_v, m_node_info_list, speed_profile.traffic_signal_penalty);
} }
// unpack last node of first segment if packed // unpack last node of first segment if packed
@ -457,8 +488,12 @@ void EdgeBasedGraphFactory::GenerateEdgeExpandedEdges(
if (turn_instruction == TurnInstruction::UTurn) if (turn_instruction == TurnInstruction::UTurn)
{ {
distance += speed_profile.u_turn_penalty; distance += speed_profile.u_turn_penalty;
DEBUG_UTURN(node_v, m_node_info_list, speed_profile.u_turn_penalty);
} }
DEBUG_TURN(node_v, m_node_info_list, first_coordinate, turn_angle, turn_penalty);
distance += turn_penalty; distance += turn_penalty;
const bool edge_is_compressed = m_compressed_edge_container.HasEntryForID(e1); const bool edge_is_compressed = m_compressed_edge_container.HasEntryForID(e1);
@ -541,6 +576,9 @@ void EdgeBasedGraphFactory::GenerateEdgeExpandedEdges(
} }
} }
} }
DEBUG_TURNS_STOP();
FlushVectorToStream(edge_data_file, original_edge_data_vector); FlushVectorToStream(edge_data_file, original_edge_data_vector);
edge_data_file.seekp(std::ios::beg); edge_data_file.seekp(std::ios::beg);

View File

@ -50,6 +50,8 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <unordered_set> #include <unordered_set>
#include <vector> #include <vector>
#include <boost/filesystem/fstream.hpp>
struct lua_State; struct lua_State;
class EdgeBasedGraphFactory class EdgeBasedGraphFactory
@ -66,12 +68,20 @@ class EdgeBasedGraphFactory
const std::vector<QueryNode> &node_info_list, const std::vector<QueryNode> &node_info_list,
SpeedProfileProperties speed_profile); SpeedProfileProperties speed_profile);
#ifdef DEBUG_GEOMETRY
void Run(const std::string &original_edge_data_filename, void Run(const std::string &original_edge_data_filename,
lua_State *lua_state, lua_State *lua_state,
const std::string &edge_segment_lookup_filename, const std::string &edge_segment_lookup_filename,
const std::string &edge_penalty_filename, const std::string &edge_penalty_filename,
const bool generate_edge_lookup const bool generate_edge_lookup,
); const std::string &debug_turns_path);
#else
void Run(const std::string &original_edge_data_filename,
lua_State *lua_state,
const std::string &edge_segment_lookup_filename,
const std::string &edge_penalty_filename,
const bool generate_edge_lookup);
#endif
void GetEdgeBasedEdges(DeallocatingVector<EdgeBasedEdge> &edges); void GetEdgeBasedEdges(DeallocatingVector<EdgeBasedEdge> &edges);
@ -103,12 +113,20 @@ class EdgeBasedGraphFactory
void CompressGeometry(); void CompressGeometry();
unsigned RenumberEdges(); unsigned RenumberEdges();
void GenerateEdgeExpandedNodes(); void GenerateEdgeExpandedNodes();
#ifdef DEBUG_GEOMETRY
void GenerateEdgeExpandedEdges(const std::string &original_edge_data_filename, void GenerateEdgeExpandedEdges(const std::string &original_edge_data_filename,
lua_State *lua_state, lua_State *lua_state,
const std::string &edge_segment_lookup_filename, const std::string &edge_segment_lookup_filename,
const std::string &edge_fixed_penalties_filename, const std::string &edge_fixed_penalties_filename,
const bool generate_edge_lookup const bool generate_edge_lookup,
); const std::string &debug_turns_path);
#else
void GenerateEdgeExpandedEdges(const std::string &original_edge_data_filename,
lua_State *lua_state,
const std::string &edge_segment_lookup_filename,
const std::string &edge_fixed_penalties_filename,
const bool generate_edge_lookup);
#endif
void InsertEdgeBasedNode(const NodeID u, const NodeID v); void InsertEdgeBasedNode(const NodeID u, const NodeID v);

View File

@ -536,6 +536,9 @@ extractor::BuildEdgeExpandedGraph(std::vector<QueryNode> &internal_to_external_n
config.edge_segment_lookup_path, config.edge_segment_lookup_path,
config.edge_penalty_path, config.edge_penalty_path,
config.generate_edge_lookup config.generate_edge_lookup
#ifdef DEBUG_GEOMETRY
, config.debug_turns_path
#endif
); );
lua_close(lua_state); lua_close(lua_state);
@ -543,11 +546,6 @@ extractor::BuildEdgeExpandedGraph(std::vector<QueryNode> &internal_to_external_n
edge_based_graph_factory.GetEdgeBasedNodes(node_based_edge_list); edge_based_graph_factory.GetEdgeBasedNodes(node_based_edge_list);
auto max_edge_id = edge_based_graph_factory.GetHighestEdgeID(); auto max_edge_id = edge_based_graph_factory.GetHighestEdgeID();
// danpat TODO: somewhere right around here, we will need to
// use the internal_to_external_node_map (which contains original OSM node ids)
// the edges from the compressed edge container
// and the edge-based-edges
const std::size_t number_of_node_based_nodes = node_based_graph->GetNumberOfNodes(); const std::size_t number_of_node_based_nodes = node_based_graph->GetNumberOfNodes();
return std::make_pair(number_of_node_based_nodes, max_edge_id); return std::make_pair(number_of_node_based_nodes, max_edge_id);
} }

View File

@ -66,6 +66,12 @@ ExtractorOptions::ParseArguments(int argc, char *argv[], ExtractorConfig &extrac
&extractor_config.generate_edge_lookup)->implicit_value(true)->default_value(false), &extractor_config.generate_edge_lookup)->implicit_value(true)->default_value(false),
"Generate a lookup table for internal edge-expanded-edge IDs to OSM node pairs"); "Generate a lookup table for internal edge-expanded-edge IDs to OSM node pairs");
#ifdef DEBUG_GEOMETRY
config_options.add_options()("debug-turns",
boost::program_options::value<std::string>(&extractor_config.debug_turns_path),
"Write out GeoJSON with turn penalty data");
#endif // DEBUG_GEOMETRY
// hidden options, will be allowed both on command line and in config file, but will not be // hidden options, will be allowed both on command line and in config file, but will not be
// shown to the user // shown to the user
boost::program_options::options_description hidden_options("Hidden options"); boost::program_options::options_description hidden_options("Hidden options");

View File

@ -62,6 +62,9 @@ struct ExtractorConfig
bool generate_edge_lookup; bool generate_edge_lookup;
std::string edge_penalty_path; std::string edge_penalty_path;
std::string edge_segment_lookup_path; std::string edge_segment_lookup_path;
#ifdef DEBUG_GEOMETRY
std::string debug_turns_path;
#endif
}; };
struct ExtractorOptions struct ExtractorOptions

View File

@ -17,7 +17,8 @@ Feature: osrm-prepare command line options: help
And stdout should contain "--threads" And stdout should contain "--threads"
And stdout should contain "--core" And stdout should contain "--core"
And stdout should contain "--level-cache" And stdout should contain "--level-cache"
And stdout should contain 18 lines And stdout should contain "--segment-speed-file"
And stdout should contain 21 lines
And it should exit with code 1 And it should exit with code 1
Scenario: osrm-prepare - Help, short Scenario: osrm-prepare - Help, short
@ -33,7 +34,8 @@ Feature: osrm-prepare command line options: help
And stdout should contain "--threads" And stdout should contain "--threads"
And stdout should contain "--core" And stdout should contain "--core"
And stdout should contain "--level-cache" And stdout should contain "--level-cache"
And stdout should contain 18 lines And stdout should contain "--segment-speed-file"
And stdout should contain 21 lines
And it should exit with code 0 And it should exit with code 0
Scenario: osrm-prepare - Help, long Scenario: osrm-prepare - Help, long
@ -49,5 +51,6 @@ Feature: osrm-prepare command line options: help
And stdout should contain "--threads" And stdout should contain "--threads"
And stdout should contain "--core" And stdout should contain "--core"
And stdout should contain "--level-cache" And stdout should contain "--level-cache"
And stdout should contain 18 lines And stdout should contain "--segment-speed-file"
And stdout should contain 21 lines
And it should exit with code 0 And it should exit with code 0

198
util/debug_geometry.hpp Normal file
View File

@ -0,0 +1,198 @@
/*
Copyright (c) 2015, Project OSRM contributors
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 DEBUG_GEOMETRY_H
#define DEBUG_GEOMETRY_H
#include "../contractor/contractor_options.hpp"
#include "../data_structures/query_node.hpp"
#ifndef DEBUG_GEOMETRY
inline void DEBUG_GEOMETRY_START(ContractorConfig & /* config */) {}
inline void DEBUG_GEOMETRY_EDGE(int /* new_segment_weight */ , double /* segment_length */,
NodeID /* previous_osm_node_id */, NodeID /* this_osm_node_id */) {}
inline void DEBUG_GEOMETRY_STOP() {}
inline void DEBUG_TURNS_START(const std::string & /* debug_turns_filename */) {}
inline void DEBUG_TURN( const NodeID /* node */, const std::vector<QueryNode>& /* m_node_info_list */,
const FixedPointCoordinate & /* first_coordinate */, const int /* turn_angle */,
const int /* turn_penalty */) {}
inline void DEBUG_UTURN( const NodeID /* node */, const std::vector<QueryNode>& /* m_node_info_list */,
const int /* uturn_penalty */ ) {}
inline void DEBUG_SIGNAL( const NodeID /* node */, const std::vector<QueryNode>& /* m_node_info_list */,
const int /* signal_penalty */ ) {}
inline void DEBUG_TURNS_STOP() {}
#else // DEBUG_GEOMETRY
#include <boost/filesystem.hpp>
#include <ctime>
#include <string>
#include <iomanip>
#include <iostream>
#include "../include/osrm/coordinate.hpp"
#include "../algorithms/coordinate_calculation.hpp"
boost::filesystem::ofstream debug_geometry_file;
bool dg_output_debug_geometry = false;
bool dg_first_debug_geometry = true;
char dg_time_buffer[80];
boost::filesystem::ofstream dg_debug_turns_file;
bool dg_output_turn_debug = false;
bool dg_first_turn_debug = true;
inline void DEBUG_GEOMETRY_START(const ContractorConfig &config)
{
time_t raw_time;
struct tm *timeinfo;
time(&raw_time);
timeinfo = localtime(&raw_time);
strftime(dg_time_buffer, 80, "%Y-%m-%d %H:%M %Z", timeinfo);
dg_output_debug_geometry = config.debug_geometry_path != "";
if (dg_output_debug_geometry)
{
debug_geometry_file.open(config.debug_geometry_path, std::ios::binary);
debug_geometry_file << "{\"type\":\"FeatureCollection\", \"features\":[" << std::endl;
}
}
inline void DEBUG_GEOMETRY_EDGE(int new_segment_weight, double segment_length, NodeID previous_osm_node_id, NodeID this_osm_node_id)
{
if (dg_output_debug_geometry)
{
if (!dg_first_debug_geometry)
debug_geometry_file << "," << std::endl;
debug_geometry_file
<< "{ \"type\":\"Feature\",\"properties\":{\"original\":false, "
"\"weight\":"
<< new_segment_weight / 10.0 << ",\"speed\":"
<< static_cast<int>(
std::floor((segment_length / new_segment_weight) * 10. * 3.6))
<< ",";
debug_geometry_file << "\"from_node\": " << previous_osm_node_id
<< ", \"to_node\": " << this_osm_node_id << ",";
debug_geometry_file << "\"timestamp\": \"" << dg_time_buffer << "\"},";
debug_geometry_file
<< "\"geometry\":{\"type\":\"LineString\",\"coordinates\":[[!!"
<< previous_osm_node_id << "!!],[!!" << this_osm_node_id << "!!]]}}"
<< std::endl;
dg_first_debug_geometry = false;
}
}
inline void DEBUG_GEOMETRY_STOP()
{
if (dg_output_debug_geometry)
{
debug_geometry_file << std::endl << "]}" << std::endl;
debug_geometry_file.close();
}
}
inline void DEBUG_TURNS_START(const std::string & debug_turns_path)
{
dg_output_turn_debug = debug_turns_path != "";
if (dg_output_turn_debug)
{
dg_debug_turns_file.open(debug_turns_path);
dg_debug_turns_file << "{\"type\":\"FeatureCollection\", \"features\":[" << std::endl;
}
}
inline void DEBUG_SIGNAL(
const NodeID node,
const std::vector<QueryNode>& m_node_info_list,
const int traffic_signal_penalty)
{
if (dg_output_turn_debug)
{
const QueryNode &nodeinfo = m_node_info_list[node];
if (!dg_first_turn_debug) dg_debug_turns_file << "," << std::endl;
dg_debug_turns_file << "{ \"type\":\"Feature\",\"properties\":{\"type\":\"trafficlights\",\"cost\":" << traffic_signal_penalty/10. << "},";
dg_debug_turns_file << " \"geometry\":{\"type\":\"Point\",\"coordinates\":[" << std::setprecision(12) << nodeinfo.lon/COORDINATE_PRECISION << "," << nodeinfo.lat/COORDINATE_PRECISION << "]}}";
dg_first_turn_debug = false;
}
}
inline void DEBUG_UTURN(
const NodeID node,
const std::vector<QueryNode>& m_node_info_list,
const int traffic_signal_penalty)
{
if (dg_output_turn_debug)
{
const QueryNode &nodeinfo = m_node_info_list[node];
if (!dg_first_turn_debug) dg_debug_turns_file << "," << std::endl;
dg_debug_turns_file << "{ \"type\":\"Feature\",\"properties\":{\"type\":\"trafficlights\",\"cost\":" << traffic_signal_penalty/10. << "},";
dg_debug_turns_file << " \"geometry\":{\"type\":\"Point\",\"coordinates\":[" << std::setprecision(12) << nodeinfo.lon/COORDINATE_PRECISION << "," << nodeinfo.lat/COORDINATE_PRECISION << "]}}";
dg_first_turn_debug = false;
}
}
inline void DEBUG_TURN(
const NodeID node,
const std::vector<QueryNode>& m_node_info_list,
const FixedPointCoordinate & first_coordinate,
const int turn_angle,
const int turn_penalty)
{
if (turn_penalty > 0 && dg_output_turn_debug)
{
const QueryNode &v = m_node_info_list[node];
const float bearing_uv = coordinate_calculation::bearing(first_coordinate,v);
float uvw_normal = bearing_uv + turn_angle/2;
while (uvw_normal >= 360.) { uvw_normal -= 360.; }
if (!dg_first_turn_debug) dg_debug_turns_file << "," << std::endl;
dg_debug_turns_file << "{ \"type\":\"Feature\",\"properties\":{\"type\":\"turn\",\"cost\":" << turn_penalty/10. << ",\"turn_angle\":" << static_cast<int>(turn_angle) << ",\"normal\":" << static_cast<int>(uvw_normal) << "},";
dg_debug_turns_file << " \"geometry\":{\"type\":\"Point\",\"coordinates\":[" << std::setprecision(12) << v.lon/COORDINATE_PRECISION << "," << v.lat/COORDINATE_PRECISION << "]}}";
dg_first_turn_debug = false;
}
}
inline void DEBUG_TURNS_STOP()
{
if (dg_output_turn_debug)
{
dg_debug_turns_file << std::endl << "]}" << std::endl;
dg_debug_turns_file.close();
}
}
#endif // DEBUG_GEOMETRY
#endif // DEBUG_GEOMETRY_H