Merge pull request #1785 from Project-OSRM/feature/weight_debugging
Adds ability to dump GeoJSON with detailed edge weight info.
This commit is contained in:
		
						commit
						d8ca58a04e
					
				| @ -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) | ||||||
|  | |||||||
| @ -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 ^ | ||||||
|  | |||||||
| @ -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 | ||||||
|  | |||||||
| @ -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) {} | ||||||
|  | |||||||
| @ -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"); | ||||||
|  | |||||||
| @ -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 | ||||||
|  | |||||||
| @ -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 | ||||||
|  | |||||||
| @ -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" | ||||||
|  | |||||||
| @ -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); | ||||||
|  | |||||||
| @ -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); | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -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); | ||||||
| } | } | ||||||
|  | |||||||
| @ -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"); | ||||||
|  | |||||||
| @ -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 | ||||||
|  | |||||||
| @ -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
									
								
							
							
						
						
									
										198
									
								
								util/debug_geometry.hpp
									
									
									
									
									
										Normal 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
 | ||||||
		Loading…
	
		Reference in New Issue
	
	Block a user