Adds .properties file to osrm-extract ouput

This file contains global properties set by the lua
profile, such as enabling uturns at vias and penalties.
This file will be consumed by the server.
This commit is contained in:
Patrick Niklaus 2016-03-21 22:42:47 +01:00
parent e10e8910f3
commit 71c336d9dd
18 changed files with 253 additions and 250 deletions

View File

@ -4,7 +4,7 @@
#define EDGE_BASED_GRAPH_FACTORY_HPP_ #define EDGE_BASED_GRAPH_FACTORY_HPP_
#include "extractor/edge_based_edge.hpp" #include "extractor/edge_based_edge.hpp"
#include "extractor/speed_profile.hpp" #include "extractor/profile_properties.hpp"
#include "extractor/restriction_map.hpp" #include "extractor/restriction_map.hpp"
#include "extractor/compressed_edge_container.hpp" #include "extractor/compressed_edge_container.hpp"
#include "extractor/edge_based_node.hpp" #include "extractor/edge_based_node.hpp"
@ -52,7 +52,7 @@ class EdgeBasedGraphFactory
const std::unordered_set<NodeID> &traffic_lights, const std::unordered_set<NodeID> &traffic_lights,
std::shared_ptr<const RestrictionMap> restriction_map, std::shared_ptr<const RestrictionMap> restriction_map,
const std::vector<QueryNode> &node_info_list, const std::vector<QueryNode> &node_info_list,
SpeedProfileProperties speed_profile, ProfileProperties profile_properties,
const util::NameTable &name_table); const util::NameTable &name_table);
void Run(const std::string &original_edge_data_filename, void Run(const std::string &original_edge_data_filename,
@ -106,7 +106,7 @@ class EdgeBasedGraphFactory
const std::unordered_set<NodeID> &m_traffic_lights; const std::unordered_set<NodeID> &m_traffic_lights;
const CompressedEdgeContainer &m_compressed_edge_container; const CompressedEdgeContainer &m_compressed_edge_container;
SpeedProfileProperties speed_profile; ProfileProperties profile_properties;
const util::NameTable &name_table; const util::NameTable &name_table;

View File

@ -40,6 +40,8 @@ namespace osrm
namespace extractor namespace extractor
{ {
class ProfileProperties;
class Extractor class Extractor
{ {
public: public:
@ -49,13 +51,15 @@ class Extractor
private: private:
ExtractorConfig config; ExtractorConfig config;
void SetupScriptingEnvironment(lua_State *myLuaState, SpeedProfileProperties &speed_profile);
std::pair<std::size_t, std::size_t> std::pair<std::size_t, std::size_t>
BuildEdgeExpandedGraph(std::vector<QueryNode> &internal_to_external_node_map, BuildEdgeExpandedGraph(lua_State* lua_state,
const ProfileProperties& profile_properties,
std::vector<QueryNode> &internal_to_external_node_map,
std::vector<EdgeBasedNode> &node_based_edge_list, std::vector<EdgeBasedNode> &node_based_edge_list,
std::vector<bool> &node_is_startpoint, std::vector<bool> &node_is_startpoint,
std::vector<EdgeWeight> &edge_based_node_weights, std::vector<EdgeWeight> &edge_based_node_weights,
util::DeallocatingVector<EdgeBasedEdge> &edge_based_edge_list); util::DeallocatingVector<EdgeBasedEdge> &edge_based_edge_list);
void WriteProfileProperties(const std::string& output_path, const ProfileProperties& properties) const;
void WriteNodeMapping(const std::vector<QueryNode> &internal_to_external_node_map); void WriteNodeMapping(const std::vector<QueryNode> &internal_to_external_node_map);
void FindComponents(unsigned max_edge_id, void FindComponents(unsigned max_edge_id,
const util::DeallocatingVector<EdgeBasedEdge> &edges, const util::DeallocatingVector<EdgeBasedEdge> &edges,

View File

@ -71,6 +71,7 @@ struct ExtractorConfig
edge_segment_lookup_path = basepath + ".osrm.edge_segment_lookup"; edge_segment_lookup_path = basepath + ".osrm.edge_segment_lookup";
edge_penalty_path = basepath + ".osrm.edge_penalties"; edge_penalty_path = basepath + ".osrm.edge_penalties";
edge_based_node_weights_output_path = basepath + ".osrm.enw"; edge_based_node_weights_output_path = basepath + ".osrm.enw";
profile_properties_output_path = basepath + ".osrm.properties";
} }
boost::filesystem::path config_file_path; boost::filesystem::path config_file_path;
@ -88,6 +89,7 @@ struct ExtractorConfig
std::string node_output_path; std::string node_output_path;
std::string rtree_nodes_output_path; std::string rtree_nodes_output_path;
std::string rtree_leafs_output_path; std::string rtree_leafs_output_path;
std::string profile_properties_output_path;
unsigned requested_num_threads; unsigned requested_num_threads;
unsigned small_component_size; unsigned small_component_size;

View File

@ -3,7 +3,6 @@
#include "util/typedefs.hpp" #include "util/typedefs.hpp"
#include "extractor/speed_profile.hpp"
#include "util/node_based_graph.hpp" #include "util/node_based_graph.hpp"
#include <memory> #include <memory>
@ -22,7 +21,7 @@ class GraphCompressor
using EdgeData = util::NodeBasedDynamicGraph::EdgeData; using EdgeData = util::NodeBasedDynamicGraph::EdgeData;
public: public:
GraphCompressor(SpeedProfileProperties speed_profile); GraphCompressor();
void Compress(const std::unordered_set<NodeID> &barrier_nodes, void Compress(const std::unordered_set<NodeID> &barrier_nodes,
const std::unordered_set<NodeID> &traffic_lights, const std::unordered_set<NodeID> &traffic_lights,
@ -34,8 +33,6 @@ class GraphCompressor
void PrintStatistics(unsigned original_number_of_nodes, void PrintStatistics(unsigned original_number_of_nodes,
unsigned original_number_of_edges, unsigned original_number_of_edges,
const util::NodeBasedDynamicGraph &graph) const; const util::NodeBasedDynamicGraph &graph) const;
SpeedProfileProperties speed_profile;
}; };
} }
} }

View File

@ -0,0 +1,46 @@
#ifndef PROFILE_PROPERTIES_HPP
#define PROFILE_PROPERTIES_HPP
namespace osrm
{
namespace extractor
{
struct ProfileProperties
{
ProfileProperties()
: traffic_signal_penalty(0), u_turn_penalty(0), allow_u_turn_at_via(false), use_turn_restrictions(false)
{
}
double GetUturnPenalty() const
{
return u_turn_penalty / 10.;
}
void SetUturnPenalty(const double u_turn_penalty_)
{
u_turn_penalty = static_cast<int>(u_turn_penalty_ * 10.);
}
double GetTrafficSignalPenalty() const
{
return traffic_signal_penalty / 10.;
}
void SetTrafficSignalPenalty(const double traffic_signal_penalty_)
{
traffic_signal_penalty = static_cast<int>(traffic_signal_penalty_ * 10.);
}
//! penalty to cross a traffic light in deci-seconds
int traffic_signal_penalty;
//! penalty to do a uturn in deci-seconds
int u_turn_penalty;
bool allow_u_turn_at_via;
bool use_turn_restrictions;
};
}
}
#endif

View File

@ -19,6 +19,8 @@ namespace osrm
namespace extractor namespace extractor
{ {
class ProfileProperties;
/** /**
* Parses the relations that represents turn restrictions. * Parses the relations that represents turn restrictions.
* *
@ -40,11 +42,10 @@ namespace extractor
class RestrictionParser class RestrictionParser
{ {
public: public:
RestrictionParser(lua_State *lua_state); RestrictionParser(lua_State *lua_state, const ProfileProperties& properties);
boost::optional<InputRestrictionContainer> TryParse(const osmium::Relation &relation) const; boost::optional<InputRestrictionContainer> TryParse(const osmium::Relation &relation) const;
private: private:
void ReadUseRestrictionsSetting(lua_State *lua_state);
void ReadRestrictionExceptions(lua_State *lua_state); void ReadRestrictionExceptions(lua_State *lua_state);
bool ShouldIgnoreRestriction(const std::string &except_tag_string) const; bool ShouldIgnoreRestriction(const std::string &except_tag_string) const;

View File

@ -1,6 +1,9 @@
#ifndef SCRIPTING_ENVIRONMENT_HPP #ifndef SCRIPTING_ENVIRONMENT_HPP
#define SCRIPTING_ENVIRONMENT_HPP #define SCRIPTING_ENVIRONMENT_HPP
#include "extractor/profile_properties.hpp"
#include "extractor/raster_source.hpp"
#include <string> #include <string>
#include <memory> #include <memory>
#include <mutex> #include <mutex>
@ -23,18 +26,28 @@ namespace extractor
class ScriptingEnvironment class ScriptingEnvironment
{ {
public: public:
struct Context
{
Context();
~Context();
ProfileProperties properties;
SourceContainer sources;
lua_State *state;
};
explicit ScriptingEnvironment(const std::string &file_name); explicit ScriptingEnvironment(const std::string &file_name);
ScriptingEnvironment(const ScriptingEnvironment &) = delete; ScriptingEnvironment(const ScriptingEnvironment &) = delete;
ScriptingEnvironment &operator=(const ScriptingEnvironment &) = delete; ScriptingEnvironment &operator=(const ScriptingEnvironment &) = delete;
lua_State *GetLuaState(); Context &GetContex();
private: private:
void InitLuaState(lua_State *lua_state); void InitContext(Context &context);
std::mutex init_mutex; std::mutex init_mutex;
std::string file_name; std::string file_name;
tbb::enumerable_thread_specific<std::shared_ptr<lua_State>> script_contexts; tbb::enumerable_thread_specific<std::shared_ptr<Context>> script_contexts;
}; };
} }
} }

View File

@ -1,23 +0,0 @@
#ifndef SPEED_PROFILE_PROPERTIES_HPP
#define SPEED_PROFILE_PROPERTIES_HPP
namespace osrm
{
namespace extractor
{
struct SpeedProfileProperties
{
SpeedProfileProperties()
: traffic_signal_penalty(0), u_turn_penalty(0), has_turn_penalty_function(false)
{
}
int traffic_signal_penalty;
int u_turn_penalty;
bool has_turn_penalty_function;
};
}
}
#endif

View File

@ -91,9 +91,10 @@ surface_speeds = {
} }
-- these need to be global because they are accesed externaly -- these need to be global because they are accesed externaly
traffic_signal_penalty = 2 properties.traffic_signal_penalty = 2
use_turn_restrictions = false properties.use_turn_restrictions = false
u_turn_penalty = 20 properties.u_turn_penalty = 20
properties.allow_u_turn_at_via = true
local obey_oneway = true local obey_oneway = true
local ignore_areas = true local ignore_areas = true

View File

@ -127,20 +127,20 @@ maxspeed_table = {
["uk:motorway"] = (70*1609)/1000 ["uk:motorway"] = (70*1609)/1000
} }
-- these need to be global because they are accesed externaly -- set profile properties
u_turn_penalty = 20 properties.u_turn_penalty = 20
traffic_signal_penalty = 2 properties.traffic_signal_penalty = 2
use_turn_restrictions = true properties.use_turn_restrictions = true
side_road_speed_multiplier = 0.8 local side_road_speed_multiplier = 0.8
local turn_penalty = 10 local turn_penalty = 10
-- Note: this biases right-side driving. Should be -- Note: this biases right-side driving. Should be
-- inverted for left-driving countries. -- inverted for left-driving countries.
local turn_bias = 1.2 local turn_bias = 1.2
local obey_oneway = true local obey_oneway = true
local ignore_areas = true local ignore_areas = true
local abs = math.abs local abs = math.abs
local min = math.min local min = math.min

View File

@ -64,9 +64,11 @@ leisure_speeds = {
["track"] = walking_speed ["track"] = walking_speed
} }
traffic_signal_penalty = 2 properties.traffic_signal_penalty = 2
u_turn_penalty = 2 properties.u_turn_penalty = 2
use_turn_restrictions = false properties.use_turn_restrictions = false
properties.allow_u_turn_at_via = true
local fallback_names = true local fallback_names = true
function get_exceptions(vector) function get_exceptions(vector)

View File

@ -16,13 +16,10 @@ speed_profile = {
-- these settings are read directly by osrm -- these settings are read directly by osrm
take_minimum_of_speeds = true properties.allow_u_turn_at_via = false
obey_oneway = true properties.use_turn_restrictions = true
obey_barriers = true properties.traffic_signal_penalty = 7 -- seconds
use_turn_restrictions = true properties.u_turn_penalty = 20
ignore_areas = true -- future feature
traffic_signal_penalty = 7 -- seconds
u_turn_penalty = 20
function limit_speed(speed, limits) function limit_speed(speed, limits)
-- don't use ipairs(), since it stops at the first nil value -- don't use ipairs(), since it stops at the first nil value

View File

@ -35,13 +35,13 @@ EdgeBasedGraphFactory::EdgeBasedGraphFactory(
const std::unordered_set<NodeID> &traffic_lights, const std::unordered_set<NodeID> &traffic_lights,
std::shared_ptr<const RestrictionMap> restriction_map, std::shared_ptr<const RestrictionMap> restriction_map,
const std::vector<QueryNode> &node_info_list, const std::vector<QueryNode> &node_info_list,
SpeedProfileProperties speed_profile, ProfileProperties profile_properties,
const util::NameTable &name_table) const util::NameTable &name_table)
: m_max_edge_id(0), m_node_info_list(node_info_list), : m_max_edge_id(0), m_node_info_list(node_info_list),
m_node_based_graph(std::move(node_based_graph)), m_node_based_graph(std::move(node_based_graph)),
m_restriction_map(std::move(restriction_map)), m_barrier_nodes(barrier_nodes), m_restriction_map(std::move(restriction_map)), m_barrier_nodes(barrier_nodes),
m_traffic_lights(traffic_lights), m_compressed_edge_container(compressed_edge_container), m_traffic_lights(traffic_lights), m_compressed_edge_container(compressed_edge_container),
speed_profile(std::move(speed_profile)), name_table(name_table) profile_properties(std::move(profile_properties)), name_table(name_table)
{ {
} }
@ -208,7 +208,7 @@ unsigned EdgeBasedGraphFactory::RenumberEdges()
// oneway streets always require this self-loop. Other streets only if a u-turn plus // oneway streets always require this self-loop. Other streets only if a u-turn plus
// traversal // traversal
// of the street takes longer than the loop // of the street takes longer than the loop
m_edge_based_node_weights.push_back(edge_data.distance + speed_profile.u_turn_penalty); m_edge_based_node_weights.push_back(edge_data.distance + profile_properties.u_turn_penalty);
BOOST_ASSERT(numbered_edges_count < m_node_based_graph->GetNumberOfEdges()); BOOST_ASSERT(numbered_edges_count < m_node_based_graph->GetNumberOfEdges());
edge_data.edge_id = numbered_edges_count; edge_data.edge_id = numbered_edges_count;
@ -277,6 +277,9 @@ void EdgeBasedGraphFactory::GenerateEdgeExpandedEdges(
{ {
util::SimpleLogger().Write() << "generating edge-expanded edges"; util::SimpleLogger().Write() << "generating edge-expanded edges";
BOOST_ASSERT(lua_state != nullptr);
const bool use_turn_function = util::lua_function_exists(lua_state, "turn_function");
std::size_t node_based_edge_counter = 0; std::size_t node_based_edge_counter = 0;
std::size_t original_edges_counter = 0; std::size_t original_edges_counter = 0;
restricted_turns_counter = 0; restricted_turns_counter = 0;
@ -338,15 +341,15 @@ void EdgeBasedGraphFactory::GenerateEdgeExpandedEdges(
unsigned distance = edge_data1.distance; unsigned distance = edge_data1.distance;
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 += profile_properties.traffic_signal_penalty;
} }
const int turn_penalty = GetTurnPenalty(turn_angle, lua_state); const int turn_penalty = use_turn_function ? GetTurnPenalty(turn_angle, lua_state) : 0;
const auto turn_instruction = turn.instruction; const auto turn_instruction = turn.instruction;
if (guidance::isUturn(turn_instruction)) if (guidance::isUturn(turn_instruction))
{ {
distance += speed_profile.u_turn_penalty; distance += profile_properties.u_turn_penalty;
} }
distance += turn_penalty; distance += turn_penalty;
@ -446,20 +449,16 @@ void EdgeBasedGraphFactory::GenerateEdgeExpandedEdges(
int EdgeBasedGraphFactory::GetTurnPenalty(double angle, lua_State *lua_state) const int EdgeBasedGraphFactory::GetTurnPenalty(double angle, lua_State *lua_state) const
{ {
BOOST_ASSERT(lua_state != nullptr);
if (speed_profile.has_turn_penalty_function) try
{ {
try // call lua profile to compute turn penalty
{ double penalty = luabind::call_function<double>(lua_state, "turn_function", 180. - angle);
// call lua profile to compute turn penalty return static_cast<int>(penalty);
double penalty = }
luabind::call_function<double>(lua_state, "turn_function", 180. - angle); catch (const luabind::error &er)
return static_cast<int>(penalty); {
} util::SimpleLogger().Write(logWARNING) << er.what();
catch (const luabind::error &er)
{
util::SimpleLogger().Write(logWARNING) << er.what();
}
} }
return 0; return 0;
} }

View File

@ -288,6 +288,8 @@ void ExtractionContainers::PrepareEdges(lua_State *segment_state)
const auto all_edges_list_end_ = all_edges_list.end(); const auto all_edges_list_end_ = all_edges_list.end();
const auto all_nodes_list_end_ = all_nodes_list.end(); const auto all_nodes_list_end_ = all_nodes_list.end();
auto has_segment_function = util::lua_function_exists(segment_state, "segment_function");
while (edge_iterator != all_edges_list_end_ && node_iterator != all_nodes_list_end_) while (edge_iterator != all_edges_list_end_ && node_iterator != all_nodes_list_end_)
{ {
// skip all invalid edges // skip all invalid edges
@ -323,7 +325,7 @@ void ExtractionContainers::PrepareEdges(lua_State *segment_state)
edge_iterator->source_coordinate, edge_iterator->source_coordinate,
util::Coordinate(node_iterator->lon, node_iterator->lat)); util::Coordinate(node_iterator->lon, node_iterator->lat));
if (util::lua_function_exists(segment_state, "segment_function")) if (has_segment_function)
{ {
luabind::call_function<void>( luabind::call_function<void>(
segment_state, "segment_function", boost::cref(edge_iterator->source_coordinate), segment_state, "segment_function", boost::cref(edge_iterator->source_coordinate),

View File

@ -48,6 +48,7 @@
#include <unordered_map> #include <unordered_map>
#include <vector> #include <vector>
#include <bitset> #include <bitset>
#include <chrono>
namespace osrm namespace osrm
{ {
@ -75,6 +76,9 @@ namespace extractor
*/ */
int Extractor::run() int Extractor::run()
{ {
// setup scripting environment
ScriptingEnvironment scripting_environment(config.profile_path.string().c_str());
try try
{ {
util::LogPolicy::GetInstance().Unmute(); util::LogPolicy::GetInstance().Unmute();
@ -89,9 +93,6 @@ int Extractor::run()
util::SimpleLogger().Write() << "Profile: " << config.profile_path.filename().string(); util::SimpleLogger().Write() << "Profile: " << config.profile_path.filename().string();
util::SimpleLogger().Write() << "Threads: " << number_of_threads; util::SimpleLogger().Write() << "Threads: " << number_of_threads;
// setup scripting environment
ScriptingEnvironment scripting_environment(config.profile_path.string().c_str());
ExtractionContainers extraction_containers; ExtractionContainers extraction_containers;
auto extractor_callbacks = util::make_unique<ExtractorCallbacks>(extraction_containers); auto extractor_callbacks = util::make_unique<ExtractorCallbacks>(extraction_containers);
@ -107,15 +108,12 @@ int Extractor::run()
util::SimpleLogger().Write() << "Parsing in progress.."; util::SimpleLogger().Write() << "Parsing in progress..";
TIMER_START(parsing); TIMER_START(parsing);
lua_State *segment_state = scripting_environment.GetLuaState(); auto& main_context = scripting_environment.GetContex();
if (util::lua_function_exists(segment_state, "source_function")) // setup raster sources
if (util::lua_function_exists(main_context.state, "source_function"))
{ {
// bind a single instance of SourceContainer class to relevant lua state luabind::call_function<void>(main_context.state, "source_function");
SourceContainer sources;
luabind::globals(segment_state)["sources"] = sources;
luabind::call_function<void>(segment_state, "source_function");
} }
std::string generator = header.get("generator"); std::string generator = header.get("generator");
@ -142,7 +140,7 @@ int Extractor::run()
tbb::concurrent_vector<boost::optional<InputRestrictionContainer>> resulting_restrictions; tbb::concurrent_vector<boost::optional<InputRestrictionContainer>> resulting_restrictions;
// setup restriction parser // setup restriction parser
const RestrictionParser restriction_parser(scripting_environment.GetLuaState()); const RestrictionParser restriction_parser(main_context.state, main_context.properties);
while (const osmium::memory::Buffer buffer = reader.read()) while (const osmium::memory::Buffer buffer = reader.read())
{ {
@ -165,7 +163,7 @@ int Extractor::run()
{ {
ExtractionNode result_node; ExtractionNode result_node;
ExtractionWay result_way; ExtractionWay result_way;
lua_State *local_state = scripting_environment.GetLuaState(); auto& local_context = scripting_environment.GetContex();
for (auto x = range.begin(), end = range.end(); x != end; ++x) for (auto x = range.begin(), end = range.end(); x != end; ++x)
{ {
@ -177,7 +175,7 @@ int Extractor::run()
result_node.clear(); result_node.clear();
++number_of_nodes; ++number_of_nodes;
luabind::call_function<void>( luabind::call_function<void>(
local_state, "node_function", local_context.state, "node_function",
boost::cref(static_cast<const osmium::Node &>(*entity)), boost::cref(static_cast<const osmium::Node &>(*entity)),
boost::ref(result_node)); boost::ref(result_node));
resulting_nodes.push_back(std::make_pair(x, result_node)); resulting_nodes.push_back(std::make_pair(x, result_node));
@ -186,7 +184,7 @@ int Extractor::run()
result_way.clear(); result_way.clear();
++number_of_ways; ++number_of_ways;
luabind::call_function<void>( luabind::call_function<void>(
local_state, "way_function", local_context.state, "way_function",
boost::cref(static_cast<const osmium::Way &>(*entity)), boost::cref(static_cast<const osmium::Way &>(*entity)),
boost::ref(result_way)); boost::ref(result_way));
resulting_ways.push_back(std::make_pair(x, result_way)); resulting_ways.push_back(std::make_pair(x, result_way));
@ -238,26 +236,29 @@ int Extractor::run()
} }
extraction_containers.PrepareData(config.output_file_name, config.restriction_file_name, extraction_containers.PrepareData(config.output_file_name, config.restriction_file_name,
config.names_file_name, segment_state); config.names_file_name, main_context.state);
WriteProfileProperties(config.profile_properties_output_path, main_context.properties);
TIMER_STOP(extracting); TIMER_STOP(extracting);
util::SimpleLogger().Write() << "extraction finished after " << TIMER_SEC(extracting) util::SimpleLogger().Write() << "extraction finished after " << TIMER_SEC(extracting)
<< "s"; << "s";
} }
// we do this for scoping
// TODO move to own functions
catch (const std::exception &e) catch (const std::exception &e)
{ {
util::SimpleLogger().Write(logWARNING) << e.what(); util::SimpleLogger().Write(logWARNING) << e.what();
return 1; return 1;
} }
try try
{ {
// Transform the node-based graph that OSM is based on into an edge-based graph // Transform the node-based graph that OSM is based on into an edge-based graph
// that is better for routing. Every edge becomes a node, and every valid // that is better for routing. Every edge becomes a node, and every valid
// movement (e.g. turn from A->B, and B->A) becomes an edge // movement (e.g. turn from A->B, and B->A) becomes an edge
// //
//
// // Create a new lua state auto& main_context = scripting_environment.GetContex();
util::SimpleLogger().Write() << "Generating edge-expanded graph representation"; util::SimpleLogger().Write() << "Generating edge-expanded graph representation";
@ -268,7 +269,9 @@ int Extractor::run()
std::vector<bool> node_is_startpoint; std::vector<bool> node_is_startpoint;
std::vector<EdgeWeight> edge_based_node_weights; std::vector<EdgeWeight> edge_based_node_weights;
std::vector<QueryNode> internal_to_external_node_map; std::vector<QueryNode> internal_to_external_node_map;
auto graph_size = BuildEdgeExpandedGraph(internal_to_external_node_map, auto graph_size = BuildEdgeExpandedGraph(main_context.state,
main_context.properties,
internal_to_external_node_map,
edge_based_node_list, node_is_startpoint, edge_based_node_list, node_is_startpoint,
edge_based_node_weights, edge_based_edge_list); edge_based_node_weights, edge_based_edge_list);
@ -314,46 +317,15 @@ int Extractor::run()
return 0; return 0;
} }
/** void Extractor::WriteProfileProperties(const std::string& output_path, const ProfileProperties& properties) const
\brief Setups scripting environment (lua-scripting)
Also initializes speed profile.
*/
void Extractor::SetupScriptingEnvironment(lua_State *lua_state,
SpeedProfileProperties &speed_profile)
{ {
// open utility libraries string library; boost::filesystem::ofstream out_stream(output_path);
luaL_openlibs(lua_state); if (!out_stream)
// adjust lua load path
util::luaAddScriptFolderToLoadPath(lua_state, config.profile_path.string().c_str());
// Now call our function in a lua script
if (0 != luaL_dofile(lua_state, config.profile_path.string().c_str()))
{ {
std::stringstream msg; throw util::exception("Could not open " + output_path + " for writing.");
msg << lua_tostring(lua_state, -1) << " occurred in scripting block";
throw util::exception(msg.str());
} }
if (0 != luaL_dostring(lua_state, "return traffic_signal_penalty\n")) out_stream.write(reinterpret_cast<const char*>(&properties), sizeof(properties));
{
std::stringstream msg;
msg << lua_tostring(lua_state, -1) << " occurred in scripting block";
throw util::exception(msg.str());
}
speed_profile.traffic_signal_penalty = 10 * lua_tointeger(lua_state, -1);
util::SimpleLogger().Write(logDEBUG) << "traffic_signal_penalty: "
<< speed_profile.traffic_signal_penalty;
if (0 != luaL_dostring(lua_state, "return u_turn_penalty\n"))
{
std::stringstream msg;
msg << lua_tostring(lua_state, -1) << " occurred in scripting block";
throw util::exception(msg.str());
}
speed_profile.u_turn_penalty = 10 * lua_tointeger(lua_state, -1);
speed_profile.has_turn_penalty_function = util::lua_function_exists(lua_state, "turn_function");
} }
void Extractor::FindComponents(unsigned max_edge_id, void Extractor::FindComponents(unsigned max_edge_id,
@ -496,18 +468,14 @@ Extractor::LoadNodeBasedGraph(std::unordered_set<NodeID> &barrier_nodes,
\brief Building an edge-expanded graph from node-based input and turn restrictions \brief Building an edge-expanded graph from node-based input and turn restrictions
*/ */
std::pair<std::size_t, std::size_t> std::pair<std::size_t, std::size_t>
Extractor::BuildEdgeExpandedGraph(std::vector<QueryNode> &internal_to_external_node_map, Extractor::BuildEdgeExpandedGraph(lua_State* lua_state,
const ProfileProperties& profile_properties,
std::vector<QueryNode> &internal_to_external_node_map,
std::vector<EdgeBasedNode> &node_based_edge_list, std::vector<EdgeBasedNode> &node_based_edge_list,
std::vector<bool> &node_is_startpoint, std::vector<bool> &node_is_startpoint,
std::vector<EdgeWeight> &edge_based_node_weights, std::vector<EdgeWeight> &edge_based_node_weights,
util::DeallocatingVector<EdgeBasedEdge> &edge_based_edge_list) util::DeallocatingVector<EdgeBasedEdge> &edge_based_edge_list)
{ {
lua_State *lua_state = luaL_newstate();
luabind::open(lua_state);
SpeedProfileProperties speed_profile;
SetupScriptingEnvironment(lua_state, speed_profile);
std::unordered_set<NodeID> barrier_nodes; std::unordered_set<NodeID> barrier_nodes;
std::unordered_set<NodeID> traffic_lights; std::unordered_set<NodeID> traffic_lights;
@ -516,7 +484,7 @@ Extractor::BuildEdgeExpandedGraph(std::vector<QueryNode> &internal_to_external_n
LoadNodeBasedGraph(barrier_nodes, traffic_lights, internal_to_external_node_map); LoadNodeBasedGraph(barrier_nodes, traffic_lights, internal_to_external_node_map);
CompressedEdgeContainer compressed_edge_container; CompressedEdgeContainer compressed_edge_container;
GraphCompressor graph_compressor(speed_profile); GraphCompressor graph_compressor;
graph_compressor.Compress(barrier_nodes, traffic_lights, *restriction_map, *node_based_graph, graph_compressor.Compress(barrier_nodes, traffic_lights, *restriction_map, *node_based_graph,
compressed_edge_container); compressed_edge_container);
@ -527,14 +495,12 @@ Extractor::BuildEdgeExpandedGraph(std::vector<QueryNode> &internal_to_external_n
EdgeBasedGraphFactory edge_based_graph_factory( EdgeBasedGraphFactory edge_based_graph_factory(
node_based_graph, compressed_edge_container, barrier_nodes, traffic_lights, node_based_graph, compressed_edge_container, barrier_nodes, traffic_lights,
std::const_pointer_cast<RestrictionMap const>(restriction_map), std::const_pointer_cast<RestrictionMap const>(restriction_map),
internal_to_external_node_map, speed_profile, name_table); internal_to_external_node_map, profile_properties, name_table);
edge_based_graph_factory.Run(config.edge_output_path, lua_state, edge_based_graph_factory.Run(config.edge_output_path, lua_state,
config.edge_segment_lookup_path, config.edge_penalty_path, config.edge_segment_lookup_path, config.edge_penalty_path,
config.generate_edge_lookup); config.generate_edge_lookup);
lua_close(lua_state);
edge_based_graph_factory.GetEdgeBasedEdges(edge_based_edge_list); edge_based_graph_factory.GetEdgeBasedEdges(edge_based_edge_list);
edge_based_graph_factory.GetEdgeBasedNodes(node_based_edge_list); edge_based_graph_factory.GetEdgeBasedNodes(node_based_edge_list);
edge_based_graph_factory.GetStartPointMarkers(node_is_startpoint); edge_based_graph_factory.GetStartPointMarkers(node_is_startpoint);

View File

@ -13,8 +13,7 @@ namespace osrm
namespace extractor namespace extractor
{ {
GraphCompressor::GraphCompressor(SpeedProfileProperties speed_profile) GraphCompressor::GraphCompressor()
: speed_profile(std::move(speed_profile))
{ {
} }

View File

@ -1,5 +1,5 @@
#include "extractor/restriction_parser.hpp" #include "extractor/restriction_parser.hpp"
#include "extractor/extraction_way.hpp" #include "extractor/profile_properties.hpp"
#include "extractor/external_memory_node.hpp" #include "extractor/external_memory_node.hpp"
#include "util/lua_util.hpp" #include "util/lua_util.hpp"
@ -33,34 +33,15 @@ int luaErrorCallback(lua_State *lua_state)
} }
} }
RestrictionParser::RestrictionParser(lua_State *lua_state) : use_turn_restrictions(true) RestrictionParser::RestrictionParser(lua_State *lua_state, const ProfileProperties &properties)
: use_turn_restrictions(properties.use_turn_restrictions)
{ {
ReadUseRestrictionsSetting(lua_state);
if (use_turn_restrictions) if (use_turn_restrictions)
{ {
ReadRestrictionExceptions(lua_state); ReadRestrictionExceptions(lua_state);
} }
} }
void RestrictionParser::ReadUseRestrictionsSetting(lua_State *lua_state)
{
if (0 == luaL_dostring(lua_state, "return use_turn_restrictions\n") &&
lua_isboolean(lua_state, -1))
{
use_turn_restrictions = lua_toboolean(lua_state, -1);
}
if (use_turn_restrictions)
{
util::SimpleLogger().Write() << "Using turn restrictions";
}
else
{
util::SimpleLogger().Write() << "Ignoring turn restrictions";
}
}
void RestrictionParser::ReadRestrictionExceptions(lua_State *lua_state) void RestrictionParser::ReadRestrictionExceptions(lua_State *lua_state)
{ {
if (util::lua_function_exists(lua_state, "get_exceptions")) if (util::lua_function_exists(lua_state, "get_exceptions"))

View File

@ -6,6 +6,7 @@
#include "extractor/internal_extractor_edge.hpp" #include "extractor/internal_extractor_edge.hpp"
#include "extractor/external_memory_node.hpp" #include "extractor/external_memory_node.hpp"
#include "extractor/raster_source.hpp" #include "extractor/raster_source.hpp"
#include "extractor/profile_properties.hpp"
#include "util/lua_util.hpp" #include "util/lua_util.hpp"
#include "util/exception.hpp" #include "util/exception.hpp"
#include "util/simple_logger.hpp" #include "util/simple_logger.hpp"
@ -51,122 +52,137 @@ int luaErrorCallback(lua_State *state)
} }
} }
ScriptingEnvironment::Context::Context() : state(luaL_newstate()) {}
ScriptingEnvironment::Context::~Context() { lua_close(state); }
ScriptingEnvironment::ScriptingEnvironment(const std::string &file_name) : file_name(file_name) ScriptingEnvironment::ScriptingEnvironment(const std::string &file_name) : file_name(file_name)
{ {
util::SimpleLogger().Write() << "Using script " << file_name; util::SimpleLogger().Write() << "Using script " << file_name;
} }
void ScriptingEnvironment::InitLuaState(lua_State *lua_state) void ScriptingEnvironment::InitContext(ScriptingEnvironment::Context &context)
{ {
typedef double (osmium::Location::*location_member_ptr_type)() const; typedef double (osmium::Location::*location_member_ptr_type)() const;
luabind::open(lua_state); luabind::open(context.state);
// open utility libraries string library; // open utility libraries string library;
luaL_openlibs(lua_state); luaL_openlibs(context.state);
util::luaAddScriptFolderToLoadPath(lua_state, file_name.c_str()); util::luaAddScriptFolderToLoadPath(context.state, file_name.c_str());
// Add our function to the state's global scope // Add our function to the state's global scope
luabind::module( luabind::module(context.state)
lua_state)[luabind::def("print", util::LUA_print<std::string>), [luabind::def("print", util::LUA_print<std::string>),
luabind::def("durationIsValid", durationIsValid), luabind::def("durationIsValid", durationIsValid),
luabind::def("parseDuration", parseDuration), luabind::def("parseDuration", parseDuration),
luabind::class_<TravelMode>("mode") luabind::class_<TravelMode>("mode")
.enum_("enums")[luabind::value("inaccessible", TRAVEL_MODE_INACCESSIBLE), .enum_("enums")[luabind::value("inaccessible", TRAVEL_MODE_INACCESSIBLE),
luabind::value("driving", TRAVEL_MODE_DRIVING), luabind::value("driving", TRAVEL_MODE_DRIVING),
luabind::value("cycling", TRAVEL_MODE_CYCLING), luabind::value("cycling", TRAVEL_MODE_CYCLING),
luabind::value("walking", TRAVEL_MODE_WALKING), luabind::value("walking", TRAVEL_MODE_WALKING),
luabind::value("ferry", TRAVEL_MODE_FERRY), luabind::value("ferry", TRAVEL_MODE_FERRY),
luabind::value("train", TRAVEL_MODE_TRAIN), luabind::value("train", TRAVEL_MODE_TRAIN),
luabind::value("pushing_bike", TRAVEL_MODE_PUSHING_BIKE), luabind::value("pushing_bike", TRAVEL_MODE_PUSHING_BIKE),
luabind::value("movable_bridge", TRAVEL_MODE_MOVABLE_BRIDGE), luabind::value("movable_bridge", TRAVEL_MODE_MOVABLE_BRIDGE),
luabind::value("steps_up", TRAVEL_MODE_STEPS_UP), luabind::value("steps_up", TRAVEL_MODE_STEPS_UP),
luabind::value("steps_down", TRAVEL_MODE_STEPS_DOWN), luabind::value("steps_down", TRAVEL_MODE_STEPS_DOWN),
luabind::value("river_up", TRAVEL_MODE_RIVER_UP), luabind::value("river_up", TRAVEL_MODE_RIVER_UP),
luabind::value("river_down", TRAVEL_MODE_RIVER_DOWN), luabind::value("river_down", TRAVEL_MODE_RIVER_DOWN),
luabind::value("route", TRAVEL_MODE_ROUTE)], luabind::value("route", TRAVEL_MODE_ROUTE)],
luabind::class_<SourceContainer>("sources") luabind::class_<SourceContainer>("sources")
.def(luabind::constructor<>()) .def(luabind::constructor<>())
.def("load", &SourceContainer::loadRasterSource) .def("load", &SourceContainer::loadRasterSource)
.def("query", &SourceContainer::getRasterDataFromSource) .def("query", &SourceContainer::getRasterDataFromSource)
.def("interpolate", &SourceContainer::getRasterInterpolateFromSource), .def("interpolate", &SourceContainer::getRasterInterpolateFromSource),
luabind::class_<const float>("constants") luabind::class_<const float>("constants")
.enum_("enums")[luabind::value("precision", COORDINATE_PRECISION)], .enum_("enums")[luabind::value("precision", COORDINATE_PRECISION)],
luabind::class_<std::vector<std::string>>("vector").def( luabind::class_<ProfileProperties>("ProfileProperties")
"Add", static_cast<void (std::vector<std::string>::*)(const std::string &)>( .def(luabind::constructor<>())
&std::vector<std::string>::push_back)), .property("traffic_signal_penalty", &ProfileProperties::GetTrafficSignalPenalty,
&ProfileProperties::SetTrafficSignalPenalty)
.property("u_turn_penalty", &ProfileProperties::GetUturnPenalty,
&ProfileProperties::SetUturnPenalty)
.def_readwrite("allow_u_turn_at_via", &ProfileProperties::allow_u_turn_at_via),
luabind::class_<osmium::Location>("Location") luabind::class_<std::vector<std::string>>("vector")
.def<location_member_ptr_type>("lat", &osmium::Location::lat) .def("Add", static_cast<void (std::vector<std::string>::*)(const std::string &)>(
.def<location_member_ptr_type>("lon", &osmium::Location::lon), &std::vector<std::string>::push_back)),
luabind::class_<osmium::Node>("Node") luabind::class_<osmium::Location>("Location")
// .def<node_member_ptr_type>("tags", &osmium::Node::tags) .def<location_member_ptr_type>("lat", &osmium::Location::lat)
.def("location", &osmium::Node::location) .def<location_member_ptr_type>("lon", &osmium::Location::lon),
.def("get_value_by_key", &osmium::Node::get_value_by_key)
.def("get_value_by_key", &get_value_by_key<osmium::Node>)
.def("id", &osmium::Node::id),
luabind::class_<ExtractionNode>("ResultNode") luabind::class_<osmium::Node>("Node")
.def_readwrite("traffic_lights", &ExtractionNode::traffic_lights) // .def<node_member_ptr_type>("tags", &osmium::Node::tags)
.def_readwrite("barrier", &ExtractionNode::barrier), .def("location", &osmium::Node::location)
.def("get_value_by_key", &osmium::Node::get_value_by_key)
.def("get_value_by_key", &get_value_by_key<osmium::Node>)
.def("id", &osmium::Node::id),
luabind::class_<ExtractionWay>("ResultWay") luabind::class_<ExtractionNode>("ResultNode")
// .def(luabind::constructor<>()) .def_readwrite("traffic_lights", &ExtractionNode::traffic_lights)
.def_readwrite("forward_speed", &ExtractionWay::forward_speed) .def_readwrite("barrier", &ExtractionNode::barrier),
.def_readwrite("backward_speed", &ExtractionWay::backward_speed)
.def_readwrite("name", &ExtractionWay::name)
.def_readwrite("roundabout", &ExtractionWay::roundabout)
.def_readwrite("is_access_restricted", &ExtractionWay::is_access_restricted)
.def_readwrite("is_startpoint", &ExtractionWay::is_startpoint)
.def_readwrite("duration", &ExtractionWay::duration)
.property("forward_mode", &ExtractionWay::get_forward_mode,
&ExtractionWay::set_forward_mode)
.property("backward_mode", &ExtractionWay::get_backward_mode,
&ExtractionWay::set_backward_mode),
luabind::class_<osmium::Way>("Way")
.def("get_value_by_key", &osmium::Way::get_value_by_key)
.def("get_value_by_key", &get_value_by_key<osmium::Way>)
.def("id", &osmium::Way::id),
luabind::class_<InternalExtractorEdge>("EdgeSource")
.def_readonly("source_coordinate", &InternalExtractorEdge::source_coordinate)
.def_readwrite("weight_data", &InternalExtractorEdge::weight_data),
luabind::class_<InternalExtractorEdge::WeightData>("WeightData")
.def_readwrite("speed", &InternalExtractorEdge::WeightData::speed),
luabind::class_<ExternalMemoryNode>("EdgeTarget")
.property("lon", &lonToDouble<ExternalMemoryNode>)
.property("lat", &latToDouble<ExternalMemoryNode>),
luabind::class_<util::Coordinate>("Coordinate")
.property("lon", &lonToDouble<util::Coordinate>)
.property("lat", &latToDouble<util::Coordinate>),
luabind::class_<RasterDatum>("RasterDatum")
.def_readonly("datum", &RasterDatum::datum)
.def("invalid_data", &RasterDatum::get_invalid)];
if (0 != luaL_dofile(lua_state, file_name.c_str())) luabind::class_<ExtractionWay>("ResultWay")
// .def(luabind::constructor<>())
.def_readwrite("forward_speed", &ExtractionWay::forward_speed)
.def_readwrite("backward_speed", &ExtractionWay::backward_speed)
.def_readwrite("name", &ExtractionWay::name)
.def_readwrite("roundabout", &ExtractionWay::roundabout)
.def_readwrite("is_access_restricted", &ExtractionWay::is_access_restricted)
.def_readwrite("is_startpoint", &ExtractionWay::is_startpoint)
.def_readwrite("duration", &ExtractionWay::duration)
.property("forward_mode", &ExtractionWay::get_forward_mode,
&ExtractionWay::set_forward_mode)
.property("backward_mode", &ExtractionWay::get_backward_mode,
&ExtractionWay::set_backward_mode),
luabind::class_<osmium::Way>("Way")
.def("get_value_by_key", &osmium::Way::get_value_by_key)
.def("get_value_by_key", &get_value_by_key<osmium::Way>)
.def("id", &osmium::Way::id),
luabind::class_<InternalExtractorEdge>("EdgeSource")
.def_readonly("source_coordinate", &InternalExtractorEdge::source_coordinate)
.def_readwrite("weight_data", &InternalExtractorEdge::weight_data),
luabind::class_<InternalExtractorEdge::WeightData>("WeightData")
.def_readwrite("speed", &InternalExtractorEdge::WeightData::speed),
luabind::class_<ExternalMemoryNode>("EdgeTarget")
.property("lon", &lonToDouble<ExternalMemoryNode>)
.property("lat", &latToDouble<ExternalMemoryNode>),
luabind::class_<util::Coordinate>("Coordinate")
.property("lon", &lonToDouble<util::Coordinate>)
.property("lat", &latToDouble<util::Coordinate>),
luabind::class_<RasterDatum>("RasterDatum")
.def_readonly("datum", &RasterDatum::datum)
.def("invalid_data", &RasterDatum::get_invalid)];
luabind::globals(context.state)["properties"] = context.properties;
luabind::globals(context.state)["sources"] = context.sources;
if (0 != luaL_dofile(context.state, file_name.c_str()))
{ {
luabind::object error_msg(luabind::from_stack(lua_state, -1)); luabind::object error_msg(luabind::from_stack(context.state, -1));
std::ostringstream error_stream; std::ostringstream error_stream;
error_stream << error_msg; error_stream << error_msg;
throw util::exception("ERROR occurred in profile script:\n" + error_stream.str()); throw util::exception("ERROR occurred in profile script:\n" + error_stream.str());
} }
} }
lua_State *ScriptingEnvironment::GetLuaState() ScriptingEnvironment::Context &ScriptingEnvironment::GetContex()
{ {
std::lock_guard<std::mutex> lock(init_mutex); std::lock_guard<std::mutex> lock(init_mutex);
bool initialized = false; bool initialized = false;
auto &ref = script_contexts.local(initialized); auto &ref = script_contexts.local(initialized);
if (!initialized) if (!initialized)
{ {
std::shared_ptr<lua_State> state(luaL_newstate(), lua_close); std::shared_ptr<Context> state = std::make_shared<Context>();
ref = state; ref = state;
InitLuaState(ref.get()); InitContext(*ref);
} }
luabind::set_pcall_callback(&luaErrorCallback); luabind::set_pcall_callback(&luaErrorCallback);
return ref.get(); return *ref;
} }
} }
} }