2016-12-06 09:13:11 -05:00
|
|
|
#include "extractor/scripting_environment_lua.hpp"
|
2016-10-25 16:22:06 -04:00
|
|
|
|
|
|
|
#include "extractor/extraction_helper_functions.hpp"
|
|
|
|
#include "extractor/extraction_node.hpp"
|
2016-05-12 12:50:10 -04:00
|
|
|
#include "extractor/extraction_segment.hpp"
|
|
|
|
#include "extractor/extraction_turn.hpp"
|
2016-10-25 16:22:06 -04:00
|
|
|
#include "extractor/extraction_way.hpp"
|
|
|
|
#include "extractor/internal_extractor_edge.hpp"
|
|
|
|
#include "extractor/profile_properties.hpp"
|
2017-07-06 20:16:40 -04:00
|
|
|
#include "extractor/query_node.hpp"
|
2016-10-25 16:22:06 -04:00
|
|
|
#include "extractor/raster_source.hpp"
|
|
|
|
#include "extractor/restriction_parser.hpp"
|
2016-10-19 23:02:41 -04:00
|
|
|
#include "util/coordinate.hpp"
|
2016-10-25 16:22:06 -04:00
|
|
|
#include "util/exception.hpp"
|
2016-12-06 09:13:11 -05:00
|
|
|
#include "util/log.hpp"
|
2016-12-20 08:57:08 -05:00
|
|
|
#include "util/lua_util.hpp"
|
2016-10-25 16:22:06 -04:00
|
|
|
#include "util/typedefs.hpp"
|
|
|
|
|
|
|
|
#include <osmium/osm.hpp>
|
|
|
|
|
|
|
|
#include <tbb/parallel_for.h>
|
|
|
|
|
|
|
|
#include <memory>
|
|
|
|
#include <sstream>
|
|
|
|
|
2016-10-19 23:02:41 -04:00
|
|
|
namespace sol
|
|
|
|
{
|
|
|
|
template <> struct is_container<osmium::Node> : std::false_type
|
|
|
|
{
|
|
|
|
};
|
|
|
|
template <> struct is_container<osmium::Way> : std::false_type
|
|
|
|
{
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
2016-10-25 16:22:06 -04:00
|
|
|
namespace osrm
|
|
|
|
{
|
|
|
|
namespace extractor
|
|
|
|
{
|
|
|
|
|
2016-10-19 23:02:41 -04:00
|
|
|
template <class T>
|
|
|
|
auto get_value_by_key(T const &object, const char *key) -> decltype(object.get_value_by_key(key))
|
|
|
|
{
|
|
|
|
auto v = object.get_value_by_key(key);
|
|
|
|
if (v && *v)
|
|
|
|
{ // non-empty string?
|
|
|
|
return v;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
return nullptr;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
template <class T, class D>
|
2016-12-20 08:57:08 -05:00
|
|
|
const char *get_value_by_key(T const &object, const char *key, D const default_value)
|
2016-10-19 23:02:41 -04:00
|
|
|
{
|
|
|
|
auto v = get_value_by_key(object, key);
|
|
|
|
if (v && *v)
|
|
|
|
{
|
|
|
|
return v;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
return default_value;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
template <class T> double latToDouble(T const &object)
|
|
|
|
{
|
|
|
|
return static_cast<double>(util::toFloating(object.lat));
|
|
|
|
}
|
|
|
|
|
|
|
|
template <class T> double lonToDouble(T const &object)
|
|
|
|
{
|
|
|
|
return static_cast<double>(util::toFloating(object.lon));
|
|
|
|
}
|
|
|
|
|
2016-10-25 16:22:06 -04:00
|
|
|
Sol2ScriptingEnvironment::Sol2ScriptingEnvironment(const std::string &file_name)
|
|
|
|
: file_name(file_name)
|
|
|
|
{
|
2016-12-06 09:13:11 -05:00
|
|
|
util::Log() << "Using script " << file_name;
|
2016-10-25 16:22:06 -04:00
|
|
|
}
|
|
|
|
|
2016-12-07 17:02:09 -05:00
|
|
|
void Sol2ScriptingEnvironment::InitContext(LuaScriptingContext &context)
|
2016-10-25 16:22:06 -04:00
|
|
|
{
|
|
|
|
context.state.open_libraries();
|
|
|
|
|
2016-10-19 23:02:41 -04:00
|
|
|
context.state["durationIsValid"] = durationIsValid;
|
|
|
|
context.state["parseDuration"] = parseDuration;
|
|
|
|
context.state["trimLaneString"] = trimLaneString;
|
|
|
|
context.state["applyAccessTokens"] = applyAccessTokens;
|
|
|
|
context.state["canonicalizeStringList"] = canonicalizeStringList;
|
|
|
|
|
|
|
|
context.state.new_enum("mode",
|
|
|
|
"inaccessible",
|
|
|
|
TRAVEL_MODE_INACCESSIBLE,
|
|
|
|
"driving",
|
|
|
|
TRAVEL_MODE_DRIVING,
|
|
|
|
"cycling",
|
|
|
|
TRAVEL_MODE_CYCLING,
|
|
|
|
"walking",
|
|
|
|
TRAVEL_MODE_WALKING,
|
|
|
|
"ferry",
|
|
|
|
TRAVEL_MODE_FERRY,
|
|
|
|
"train",
|
|
|
|
TRAVEL_MODE_TRAIN,
|
|
|
|
"pushing_bike",
|
|
|
|
TRAVEL_MODE_PUSHING_BIKE,
|
|
|
|
"steps_up",
|
|
|
|
TRAVEL_MODE_STEPS_UP,
|
|
|
|
"steps_down",
|
|
|
|
TRAVEL_MODE_STEPS_DOWN,
|
|
|
|
"river_up",
|
|
|
|
TRAVEL_MODE_RIVER_UP,
|
|
|
|
"river_down",
|
|
|
|
TRAVEL_MODE_RIVER_DOWN,
|
|
|
|
"route",
|
|
|
|
TRAVEL_MODE_ROUTE);
|
|
|
|
|
|
|
|
context.state.new_enum("road_priority_class",
|
|
|
|
"motorway",
|
|
|
|
extractor::guidance::RoadPriorityClass::MOTORWAY,
|
|
|
|
"trunk",
|
|
|
|
extractor::guidance::RoadPriorityClass::TRUNK,
|
|
|
|
"primary",
|
|
|
|
extractor::guidance::RoadPriorityClass::PRIMARY,
|
|
|
|
"secondary",
|
|
|
|
extractor::guidance::RoadPriorityClass::SECONDARY,
|
|
|
|
"tertiary",
|
|
|
|
extractor::guidance::RoadPriorityClass::TERTIARY,
|
|
|
|
"main_residential",
|
|
|
|
extractor::guidance::RoadPriorityClass::MAIN_RESIDENTIAL,
|
|
|
|
"side_residential",
|
|
|
|
extractor::guidance::RoadPriorityClass::SIDE_RESIDENTIAL,
|
|
|
|
"link_road",
|
|
|
|
extractor::guidance::RoadPriorityClass::LINK_ROAD,
|
|
|
|
"bike_path",
|
|
|
|
extractor::guidance::RoadPriorityClass::BIKE_PATH,
|
|
|
|
"foot_path",
|
|
|
|
extractor::guidance::RoadPriorityClass::FOOT_PATH,
|
|
|
|
"connectivity",
|
|
|
|
extractor::guidance::RoadPriorityClass::CONNECTIVITY);
|
|
|
|
|
2016-05-12 12:50:10 -04:00
|
|
|
context.state.new_enum("turn_type",
|
|
|
|
"invalid",
|
|
|
|
extractor::guidance::TurnType::Invalid,
|
|
|
|
"new_name",
|
|
|
|
extractor::guidance::TurnType::NewName,
|
|
|
|
"continue",
|
|
|
|
extractor::guidance::TurnType::Continue,
|
|
|
|
"turn",
|
|
|
|
extractor::guidance::TurnType::Turn,
|
|
|
|
"merge",
|
|
|
|
extractor::guidance::TurnType::Merge,
|
|
|
|
"on_ramp",
|
|
|
|
extractor::guidance::TurnType::OnRamp,
|
|
|
|
"off_ramp",
|
|
|
|
extractor::guidance::TurnType::OffRamp,
|
|
|
|
"fork",
|
|
|
|
extractor::guidance::TurnType::Fork,
|
|
|
|
"end_of_road",
|
|
|
|
extractor::guidance::TurnType::EndOfRoad,
|
|
|
|
"notification",
|
|
|
|
extractor::guidance::TurnType::Notification,
|
|
|
|
"enter_roundabout",
|
|
|
|
extractor::guidance::TurnType::EnterRoundabout,
|
|
|
|
"enter_and_exit_roundabout",
|
|
|
|
extractor::guidance::TurnType::EnterAndExitRoundabout,
|
|
|
|
"enter_rotary",
|
|
|
|
extractor::guidance::TurnType::EnterRotary,
|
|
|
|
"enter_and_exit_rotary",
|
|
|
|
extractor::guidance::TurnType::EnterAndExitRotary,
|
|
|
|
"enter_roundabout_intersection",
|
|
|
|
extractor::guidance::TurnType::EnterRoundaboutIntersection,
|
|
|
|
"enter_and_exit_roundabout_intersection",
|
|
|
|
extractor::guidance::TurnType::EnterAndExitRoundaboutIntersection,
|
|
|
|
"use_lane",
|
2017-07-14 06:07:18 -04:00
|
|
|
extractor::guidance::TurnType::Suppressed,
|
2016-05-12 12:50:10 -04:00
|
|
|
"no_turn",
|
|
|
|
extractor::guidance::TurnType::NoTurn,
|
|
|
|
"suppressed",
|
|
|
|
extractor::guidance::TurnType::Suppressed,
|
|
|
|
"enter_roundabout_at_exit",
|
|
|
|
extractor::guidance::TurnType::EnterRoundaboutAtExit,
|
|
|
|
"exit_roundabout",
|
|
|
|
extractor::guidance::TurnType::ExitRoundabout,
|
|
|
|
"enter_rotary_at_exit",
|
|
|
|
extractor::guidance::TurnType::EnterRotaryAtExit,
|
|
|
|
"exit_rotary",
|
|
|
|
extractor::guidance::TurnType::ExitRotary,
|
|
|
|
"enter_roundabout_intersection_at_exit",
|
|
|
|
extractor::guidance::TurnType::EnterRoundaboutIntersectionAtExit,
|
|
|
|
"exit_roundabout_intersection",
|
|
|
|
extractor::guidance::TurnType::ExitRoundaboutIntersection,
|
|
|
|
"stay_on_roundabout",
|
|
|
|
extractor::guidance::TurnType::StayOnRoundabout,
|
|
|
|
"sliproad",
|
|
|
|
extractor::guidance::TurnType::Sliproad);
|
|
|
|
|
|
|
|
context.state.new_enum("direction_modifier",
|
|
|
|
"u_turn",
|
|
|
|
extractor::guidance::DirectionModifier::UTurn,
|
|
|
|
"sharp_right",
|
|
|
|
extractor::guidance::DirectionModifier::SharpRight,
|
|
|
|
"right",
|
|
|
|
extractor::guidance::DirectionModifier::Right,
|
|
|
|
"slight_right",
|
|
|
|
extractor::guidance::DirectionModifier::SlightRight,
|
|
|
|
"straight",
|
|
|
|
extractor::guidance::DirectionModifier::Straight,
|
|
|
|
"slight_left",
|
|
|
|
extractor::guidance::DirectionModifier::SlightLeft,
|
|
|
|
"left",
|
|
|
|
extractor::guidance::DirectionModifier::Left,
|
|
|
|
"sharp_left",
|
|
|
|
extractor::guidance::DirectionModifier::SharpLeft);
|
|
|
|
|
2017-05-18 08:27:28 -04:00
|
|
|
context.state.new_usertype<RasterContainer>("raster",
|
2016-10-19 23:02:41 -04:00
|
|
|
"load",
|
2017-05-18 08:27:28 -04:00
|
|
|
&RasterContainer::LoadRasterSource,
|
2016-10-19 23:02:41 -04:00
|
|
|
"query",
|
2017-05-18 08:27:28 -04:00
|
|
|
&RasterContainer::GetRasterDataFromSource,
|
2016-10-19 23:02:41 -04:00
|
|
|
"interpolate",
|
2017-05-18 08:27:28 -04:00
|
|
|
&RasterContainer::GetRasterInterpolateFromSource);
|
2016-10-19 23:02:41 -04:00
|
|
|
|
|
|
|
context.state.new_usertype<ProfileProperties>(
|
|
|
|
"ProfileProperties",
|
|
|
|
"traffic_signal_penalty",
|
|
|
|
sol::property(&ProfileProperties::GetTrafficSignalPenalty,
|
|
|
|
&ProfileProperties::SetTrafficSignalPenalty),
|
|
|
|
"u_turn_penalty",
|
2016-05-12 12:50:10 -04:00
|
|
|
sol::property(&ProfileProperties::GetUturnPenalty, &ProfileProperties::SetUturnPenalty),
|
2016-10-19 23:02:41 -04:00
|
|
|
"max_speed_for_map_matching",
|
|
|
|
sol::property(&ProfileProperties::GetMaxSpeedForMapMatching,
|
|
|
|
&ProfileProperties::SetMaxSpeedForMapMatching),
|
|
|
|
"continue_straight_at_waypoint",
|
|
|
|
&ProfileProperties::continue_straight_at_waypoint,
|
|
|
|
"use_turn_restrictions",
|
|
|
|
&ProfileProperties::use_turn_restrictions,
|
|
|
|
"left_hand_driving",
|
2016-05-12 12:50:10 -04:00
|
|
|
&ProfileProperties::left_hand_driving,
|
|
|
|
"weight_precision",
|
|
|
|
&ProfileProperties::weight_precision,
|
|
|
|
"weight_name",
|
2017-03-20 09:34:25 -04:00
|
|
|
sol::property(&ProfileProperties::SetWeightName, &ProfileProperties::GetWeightName),
|
|
|
|
"max_turn_weight",
|
2017-03-29 17:48:57 -04:00
|
|
|
sol::property(&ProfileProperties::GetMaxTurnWeight),
|
|
|
|
"force_split_edges",
|
2017-06-12 17:46:29 -04:00
|
|
|
&ProfileProperties::force_split_edges,
|
|
|
|
"call_tagless_node_function",
|
|
|
|
&ProfileProperties::call_tagless_node_function);
|
2016-10-19 23:02:41 -04:00
|
|
|
|
|
|
|
context.state.new_usertype<std::vector<std::string>>(
|
|
|
|
"vector",
|
|
|
|
"Add",
|
|
|
|
static_cast<void (std::vector<std::string>::*)(const std::string &)>(
|
|
|
|
&std::vector<std::string>::push_back));
|
|
|
|
|
2016-12-20 08:57:08 -05:00
|
|
|
context.state.new_usertype<osmium::Location>("Location",
|
|
|
|
"lat",
|
|
|
|
&osmium::Location::lat,
|
|
|
|
"lon",
|
|
|
|
&osmium::Location::lon,
|
|
|
|
"valid",
|
|
|
|
&osmium::Location::valid);
|
2016-10-19 23:02:41 -04:00
|
|
|
|
2016-12-17 09:38:14 -05:00
|
|
|
context.state.new_usertype<osmium::Way>(
|
|
|
|
"Way",
|
|
|
|
"get_value_by_key",
|
|
|
|
&get_value_by_key<osmium::Way>,
|
|
|
|
"id",
|
|
|
|
&osmium::Way::id,
|
|
|
|
"get_nodes",
|
2016-11-29 09:25:39 -05:00
|
|
|
[](const osmium::Way &way) { return sol::as_table(way.nodes()); },
|
|
|
|
"version",
|
|
|
|
&osmium::Way::version);
|
2016-10-19 23:02:41 -04:00
|
|
|
|
|
|
|
context.state.new_usertype<osmium::Node>("Node",
|
|
|
|
"location",
|
|
|
|
&osmium::Node::location,
|
|
|
|
"get_value_by_key",
|
|
|
|
&get_value_by_key<osmium::Node>,
|
|
|
|
"id",
|
2016-11-29 09:25:39 -05:00
|
|
|
&osmium::Node::id,
|
|
|
|
"version",
|
|
|
|
&osmium::Way::version);
|
2016-10-19 23:02:41 -04:00
|
|
|
|
|
|
|
context.state.new_usertype<ExtractionNode>("ResultNode",
|
|
|
|
"traffic_lights",
|
|
|
|
&ExtractionNode::traffic_lights,
|
|
|
|
"barrier",
|
|
|
|
&ExtractionNode::barrier);
|
|
|
|
|
|
|
|
context.state.new_usertype<guidance::RoadClassification>(
|
|
|
|
"RoadClassification",
|
|
|
|
"motorway_class",
|
|
|
|
sol::property(&guidance::RoadClassification::IsMotorwayClass,
|
|
|
|
&guidance::RoadClassification::SetMotorwayFlag),
|
|
|
|
"link_class",
|
|
|
|
sol::property(&guidance::RoadClassification::IsLinkClass,
|
|
|
|
&guidance::RoadClassification::SetLinkClass),
|
|
|
|
"may_be_ignored",
|
|
|
|
sol::property(&guidance::RoadClassification::IsLowPriorityRoadClass,
|
|
|
|
&guidance::RoadClassification::SetLowPriorityFlag),
|
|
|
|
"road_priority_class",
|
|
|
|
sol::property(&guidance::RoadClassification::GetClass,
|
|
|
|
&guidance::RoadClassification::SetClass),
|
|
|
|
"num_lanes",
|
|
|
|
sol::property(&guidance::RoadClassification::GetNumberOfLanes,
|
|
|
|
&guidance::RoadClassification::SetNumberOfLanes));
|
|
|
|
|
|
|
|
context.state.new_usertype<ExtractionWay>(
|
|
|
|
"ResultWay",
|
|
|
|
"forward_speed",
|
|
|
|
&ExtractionWay::forward_speed,
|
|
|
|
"backward_speed",
|
|
|
|
&ExtractionWay::backward_speed,
|
2016-05-12 12:50:10 -04:00
|
|
|
"forward_rate",
|
|
|
|
&ExtractionWay::forward_rate,
|
|
|
|
"backward_rate",
|
|
|
|
&ExtractionWay::backward_rate,
|
2016-10-19 23:02:41 -04:00
|
|
|
"name",
|
|
|
|
sol::property(&ExtractionWay::GetName, &ExtractionWay::SetName),
|
|
|
|
"ref",
|
|
|
|
sol::property(&ExtractionWay::GetRef, &ExtractionWay::SetRef),
|
|
|
|
"pronunciation",
|
|
|
|
sol::property(&ExtractionWay::GetPronunciation, &ExtractionWay::SetPronunciation),
|
|
|
|
"destinations",
|
|
|
|
sol::property(&ExtractionWay::GetDestinations, &ExtractionWay::SetDestinations),
|
2017-06-29 16:12:25 -04:00
|
|
|
"exits",
|
|
|
|
sol::property(&ExtractionWay::GetExits, &ExtractionWay::SetExits),
|
2016-10-19 23:02:41 -04:00
|
|
|
"turn_lanes_forward",
|
|
|
|
sol::property(&ExtractionWay::GetTurnLanesForward, &ExtractionWay::SetTurnLanesForward),
|
|
|
|
"turn_lanes_backward",
|
|
|
|
sol::property(&ExtractionWay::GetTurnLanesBackward, &ExtractionWay::SetTurnLanesBackward),
|
|
|
|
"duration",
|
|
|
|
&ExtractionWay::duration,
|
2016-05-12 12:50:10 -04:00
|
|
|
"weight",
|
|
|
|
&ExtractionWay::weight,
|
2016-10-19 23:02:41 -04:00
|
|
|
"road_classification",
|
|
|
|
&ExtractionWay::road_classification,
|
2017-06-27 18:01:05 -04:00
|
|
|
"forward_classes",
|
|
|
|
&ExtractionWay::forward_classes,
|
|
|
|
"backward_classes",
|
|
|
|
&ExtractionWay::backward_classes,
|
2016-10-19 23:02:41 -04:00
|
|
|
"forward_mode",
|
2017-03-29 06:36:54 -04:00
|
|
|
sol::property([](const ExtractionWay &way) { return way.forward_travel_mode; },
|
|
|
|
[](ExtractionWay &way, TravelMode mode) { way.forward_travel_mode = mode; }),
|
2016-10-19 23:02:41 -04:00
|
|
|
"backward_mode",
|
2017-03-29 06:36:54 -04:00
|
|
|
sol::property([](const ExtractionWay &way) { return way.backward_travel_mode; },
|
|
|
|
[](ExtractionWay &way, TravelMode mode) { way.backward_travel_mode = mode; }),
|
|
|
|
"roundabout",
|
|
|
|
sol::property([](const ExtractionWay &way) { return way.roundabout; },
|
|
|
|
[](ExtractionWay &way, bool flag) { way.roundabout = flag; }),
|
|
|
|
"circular",
|
|
|
|
sol::property([](const ExtractionWay &way) { return way.circular; },
|
|
|
|
[](ExtractionWay &way, bool flag) { way.circular = flag; }),
|
|
|
|
"is_startpoint",
|
|
|
|
sol::property([](const ExtractionWay &way) { return way.is_startpoint; },
|
|
|
|
[](ExtractionWay &way, bool flag) { way.is_startpoint = flag; }),
|
2017-02-14 06:59:16 -05:00
|
|
|
"forward_restricted",
|
2017-03-29 06:36:54 -04:00
|
|
|
sol::property([](const ExtractionWay &way) { return way.forward_restricted; },
|
|
|
|
[](ExtractionWay &way, bool flag) { way.forward_restricted = flag; }),
|
2017-02-14 06:59:16 -05:00
|
|
|
"backward_restricted",
|
2017-03-29 06:36:54 -04:00
|
|
|
sol::property([](const ExtractionWay &way) { return way.backward_restricted; },
|
2017-03-29 17:48:57 -04:00
|
|
|
[](ExtractionWay &way, bool flag) { way.backward_restricted = flag; }));
|
2016-10-19 23:02:41 -04:00
|
|
|
|
2016-05-12 12:50:10 -04:00
|
|
|
context.state.new_usertype<ExtractionSegment>("ExtractionSegment",
|
|
|
|
"source",
|
|
|
|
&ExtractionSegment::source,
|
|
|
|
"target",
|
|
|
|
&ExtractionSegment::target,
|
|
|
|
"distance",
|
|
|
|
&ExtractionSegment::distance,
|
|
|
|
"weight",
|
|
|
|
&ExtractionSegment::weight,
|
|
|
|
"duration",
|
|
|
|
&ExtractionSegment::duration);
|
|
|
|
|
|
|
|
context.state.new_usertype<ExtractionTurn>("ExtractionTurn",
|
|
|
|
"angle",
|
|
|
|
&ExtractionTurn::angle,
|
|
|
|
"turn_type",
|
|
|
|
&ExtractionTurn::turn_type,
|
|
|
|
"direction_modifier",
|
|
|
|
&ExtractionTurn::direction_modifier,
|
|
|
|
"has_traffic_light",
|
|
|
|
&ExtractionTurn::has_traffic_light,
|
|
|
|
"weight",
|
|
|
|
&ExtractionTurn::weight,
|
|
|
|
"duration",
|
2017-02-14 06:59:16 -05:00
|
|
|
&ExtractionTurn::duration,
|
|
|
|
"source_restricted",
|
|
|
|
&ExtractionTurn::source_restricted,
|
|
|
|
"target_restricted",
|
|
|
|
&ExtractionTurn::target_restricted);
|
2016-05-12 12:50:10 -04:00
|
|
|
|
2016-10-19 23:02:41 -04:00
|
|
|
// Keep in mind .location is undefined since we're not using libosmium's location cache
|
|
|
|
context.state.new_usertype<osmium::NodeRef>("NodeRef", "id", &osmium::NodeRef::ref);
|
|
|
|
|
|
|
|
context.state.new_usertype<InternalExtractorEdge>("EdgeSource",
|
|
|
|
"source_coordinate",
|
|
|
|
&InternalExtractorEdge::source_coordinate,
|
2016-05-12 12:50:10 -04:00
|
|
|
"weight",
|
|
|
|
&InternalExtractorEdge::weight_data,
|
|
|
|
"duration",
|
|
|
|
&InternalExtractorEdge::duration_data);
|
2016-10-19 23:02:41 -04:00
|
|
|
|
2017-07-06 20:16:40 -04:00
|
|
|
context.state.new_usertype<QueryNode>(
|
|
|
|
"EdgeTarget", "lon", &lonToDouble<QueryNode>, "lat", &latToDouble<QueryNode>);
|
2016-10-19 23:02:41 -04:00
|
|
|
|
2016-12-20 08:57:08 -05:00
|
|
|
context.state.new_usertype<util::Coordinate>("Coordinate",
|
|
|
|
"lon",
|
|
|
|
sol::property(&lonToDouble<util::Coordinate>),
|
|
|
|
"lat",
|
|
|
|
sol::property(&latToDouble<util::Coordinate>));
|
2016-10-19 23:02:41 -04:00
|
|
|
|
|
|
|
context.state.new_usertype<RasterDatum>(
|
|
|
|
"RasterDatum", "datum", &RasterDatum::datum, "invalid_data", &RasterDatum::get_invalid);
|
|
|
|
|
2017-05-18 08:27:28 -04:00
|
|
|
// the "properties" global is only used in v1 of the api, but we don't know
|
|
|
|
// the version until we have read the file. so we have to declare it in any case.
|
|
|
|
// we will then clear it for v2 profiles after reading the file
|
2016-10-19 23:02:41 -04:00
|
|
|
context.state["properties"] = &context.properties;
|
|
|
|
|
|
|
|
//
|
|
|
|
// end of register block
|
|
|
|
//
|
2016-10-25 16:22:06 -04:00
|
|
|
|
|
|
|
util::luaAddScriptFolderToLoadPath(context.state.lua_state(), file_name.c_str());
|
|
|
|
|
2017-05-18 08:27:28 -04:00
|
|
|
sol::optional<sol::table> function_table = context.state.script_file(file_name);
|
2016-05-12 12:50:10 -04:00
|
|
|
|
|
|
|
// Check profile API version
|
2016-12-01 17:10:56 -05:00
|
|
|
auto maybe_version = context.state.get<sol::optional<int>>("api_version");
|
|
|
|
if (maybe_version)
|
2016-12-17 09:38:14 -05:00
|
|
|
context.api_version = *maybe_version;
|
2017-05-18 08:27:28 -04:00
|
|
|
else
|
|
|
|
{
|
|
|
|
context.api_version = 0;
|
2016-12-17 09:38:14 -05:00
|
|
|
}
|
2016-12-01 17:10:56 -05:00
|
|
|
|
|
|
|
if (context.api_version < SUPPORTED_MIN_API_VERSION ||
|
2016-12-17 09:38:14 -05:00
|
|
|
context.api_version > SUPPORTED_MAX_API_VERSION)
|
2016-12-01 17:10:56 -05:00
|
|
|
{
|
|
|
|
throw util::exception("Invalid profile API version " + std::to_string(context.api_version) +
|
|
|
|
" only versions from " + std::to_string(SUPPORTED_MIN_API_VERSION) +
|
|
|
|
" to " + std::to_string(SUPPORTED_MAX_API_VERSION) +
|
|
|
|
" are supported." + SOURCE_REF);
|
|
|
|
}
|
2016-05-12 12:50:10 -04:00
|
|
|
|
2017-05-18 08:27:28 -04:00
|
|
|
util::Log() << "Using profile api version " << context.api_version;
|
|
|
|
|
|
|
|
// version-dependent parts of the api
|
2016-05-12 12:50:10 -04:00
|
|
|
switch (context.api_version)
|
|
|
|
{
|
2017-05-18 08:27:28 -04:00
|
|
|
case 2:
|
|
|
|
{
|
|
|
|
// clear global not used in v2
|
|
|
|
context.state["properties"] = sol::nullopt;
|
|
|
|
|
|
|
|
// check function table
|
|
|
|
if (function_table == sol::nullopt)
|
|
|
|
throw util::exception("Profile must return a function table.");
|
|
|
|
|
|
|
|
// setup helpers
|
|
|
|
context.state["raster"] = &context.raster_sources;
|
|
|
|
|
|
|
|
// set constants
|
|
|
|
context.state.new_enum("constants",
|
|
|
|
"precision",
|
|
|
|
COORDINATE_PRECISION,
|
|
|
|
"max_turn_weight",
|
|
|
|
std::numeric_limits<TurnPenalty>::max());
|
|
|
|
|
|
|
|
// call initialize function
|
|
|
|
sol::function setup_function = function_table.value()["setup"];
|
|
|
|
if (!setup_function.valid())
|
|
|
|
throw util::exception("Profile must have an setup() function.");
|
|
|
|
sol::optional<sol::table> profile_table = setup_function();
|
|
|
|
if (profile_table == sol::nullopt)
|
|
|
|
throw util::exception("Profile setup() must return a table.");
|
|
|
|
else
|
|
|
|
context.profile_table = profile_table.value();
|
|
|
|
|
|
|
|
// store functions
|
|
|
|
context.turn_function = function_table.value()["process_turn"];
|
|
|
|
context.node_function = function_table.value()["process_node"];
|
|
|
|
context.way_function = function_table.value()["process_way"];
|
|
|
|
context.segment_function = function_table.value()["process_segment"];
|
|
|
|
|
|
|
|
context.has_turn_penalty_function = context.turn_function.valid();
|
|
|
|
context.has_node_function = context.node_function.valid();
|
|
|
|
context.has_way_function = context.way_function.valid();
|
|
|
|
context.has_segment_function = context.segment_function.valid();
|
|
|
|
|
|
|
|
// read properties from 'profile.properties' table
|
|
|
|
sol::table properties = context.profile_table["properties"];
|
|
|
|
if (properties.valid())
|
|
|
|
{
|
|
|
|
sol::optional<std::string> weight_name = properties["weight_name"];
|
|
|
|
if (weight_name != sol::nullopt)
|
|
|
|
context.properties.SetWeightName(weight_name.value());
|
|
|
|
|
|
|
|
sol::optional<std::int32_t> traffic_signal_penalty =
|
|
|
|
properties["traffic_signal_penalty"];
|
|
|
|
if (traffic_signal_penalty != sol::nullopt)
|
|
|
|
context.properties.SetTrafficSignalPenalty(traffic_signal_penalty.value());
|
|
|
|
|
|
|
|
sol::optional<std::int32_t> u_turn_penalty = properties["u_turn_penalty"];
|
|
|
|
if (u_turn_penalty != sol::nullopt)
|
|
|
|
context.properties.SetUturnPenalty(u_turn_penalty.value());
|
|
|
|
|
|
|
|
sol::optional<double> max_speed_for_map_matching =
|
|
|
|
properties["max_speed_for_map_matching"];
|
|
|
|
if (max_speed_for_map_matching != sol::nullopt)
|
|
|
|
context.properties.SetMaxSpeedForMapMatching(max_speed_for_map_matching.value());
|
|
|
|
|
|
|
|
sol::optional<bool> continue_straight_at_waypoint =
|
|
|
|
properties["continue_straight_at_waypoint"];
|
|
|
|
if (continue_straight_at_waypoint != sol::nullopt)
|
|
|
|
context.properties.continue_straight_at_waypoint =
|
|
|
|
continue_straight_at_waypoint.value();
|
|
|
|
|
|
|
|
sol::optional<bool> use_turn_restrictions = properties["use_turn_restrictions"];
|
|
|
|
if (use_turn_restrictions != sol::nullopt)
|
|
|
|
context.properties.use_turn_restrictions = use_turn_restrictions.value();
|
|
|
|
|
|
|
|
sol::optional<bool> left_hand_driving = properties["left_hand_driving"];
|
|
|
|
if (left_hand_driving != sol::nullopt)
|
|
|
|
context.properties.left_hand_driving = left_hand_driving.value();
|
|
|
|
|
|
|
|
sol::optional<unsigned> weight_precision = properties["weight_precision"];
|
|
|
|
if (weight_precision != sol::nullopt)
|
|
|
|
context.properties.weight_precision = weight_precision.value();
|
|
|
|
|
|
|
|
sol::optional<bool> force_split_edges = properties["force_split_edges"];
|
|
|
|
if (force_split_edges != sol::nullopt)
|
|
|
|
context.properties.force_split_edges = force_split_edges.value();
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
2016-05-12 12:50:10 -04:00
|
|
|
case 1:
|
2017-05-18 08:27:28 -04:00
|
|
|
{
|
|
|
|
// cache references to functions for faster execution
|
|
|
|
context.turn_function = context.state["turn_function"];
|
|
|
|
context.node_function = context.state["node_function"];
|
|
|
|
context.way_function = context.state["way_function"];
|
|
|
|
context.segment_function = context.state["segment_function"];
|
|
|
|
|
|
|
|
context.has_turn_penalty_function = context.turn_function.valid();
|
|
|
|
context.has_node_function = context.node_function.valid();
|
|
|
|
context.has_way_function = context.way_function.valid();
|
|
|
|
context.has_segment_function = context.segment_function.valid();
|
|
|
|
|
|
|
|
// setup helpers
|
|
|
|
context.state["sources"] = &context.raster_sources;
|
|
|
|
|
|
|
|
// set constants
|
|
|
|
context.state.new_enum("constants", "precision", COORDINATE_PRECISION);
|
|
|
|
|
2016-05-12 12:50:10 -04:00
|
|
|
BOOST_ASSERT(context.properties.GetUturnPenalty() == 0);
|
|
|
|
BOOST_ASSERT(context.properties.GetTrafficSignalPenalty() == 0);
|
2017-05-18 08:27:28 -04:00
|
|
|
|
|
|
|
// call source_function if present
|
|
|
|
sol::function source_function = context.state["source_function"];
|
|
|
|
if (source_function.valid())
|
|
|
|
{
|
|
|
|
source_function();
|
|
|
|
}
|
|
|
|
|
2016-05-12 12:50:10 -04:00
|
|
|
break;
|
2017-05-18 08:27:28 -04:00
|
|
|
}
|
2016-05-12 12:50:10 -04:00
|
|
|
case 0:
|
2017-05-18 08:27:28 -04:00
|
|
|
// cache references to functions for faster execution
|
|
|
|
context.turn_function = context.state["turn_function"];
|
|
|
|
context.node_function = context.state["node_function"];
|
|
|
|
context.way_function = context.state["way_function"];
|
|
|
|
context.segment_function = context.state["segment_function"];
|
|
|
|
|
|
|
|
context.has_turn_penalty_function = context.turn_function.valid();
|
|
|
|
context.has_node_function = context.node_function.valid();
|
|
|
|
context.has_way_function = context.way_function.valid();
|
|
|
|
context.has_segment_function = context.segment_function.valid();
|
|
|
|
|
2016-05-12 12:50:10 -04:00
|
|
|
BOOST_ASSERT(context.properties.GetWeightName() == "duration");
|
|
|
|
break;
|
|
|
|
}
|
2016-10-25 16:22:06 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
const ProfileProperties &Sol2ScriptingEnvironment::GetProfileProperties()
|
|
|
|
{
|
|
|
|
return GetSol2Context().properties;
|
|
|
|
}
|
|
|
|
|
2016-12-07 17:02:09 -05:00
|
|
|
LuaScriptingContext &Sol2ScriptingEnvironment::GetSol2Context()
|
2016-10-25 16:22:06 -04:00
|
|
|
{
|
|
|
|
std::lock_guard<std::mutex> lock(init_mutex);
|
|
|
|
bool initialized = false;
|
|
|
|
auto &ref = script_contexts.local(initialized);
|
|
|
|
if (!initialized)
|
|
|
|
{
|
2016-12-07 17:02:09 -05:00
|
|
|
ref = std::make_unique<LuaScriptingContext>();
|
2016-10-25 16:22:06 -04:00
|
|
|
InitContext(*ref);
|
|
|
|
}
|
|
|
|
|
|
|
|
return *ref;
|
|
|
|
}
|
|
|
|
|
|
|
|
void Sol2ScriptingEnvironment::ProcessElements(
|
2017-06-08 17:04:48 -04:00
|
|
|
const osmium::memory::Buffer &buffer,
|
2016-10-25 16:22:06 -04:00
|
|
|
const RestrictionParser &restriction_parser,
|
2017-06-08 17:04:48 -04:00
|
|
|
std::vector<std::pair<const osmium::Node &, ExtractionNode>> &resulting_nodes,
|
|
|
|
std::vector<std::pair<const osmium::Way &, ExtractionWay>> &resulting_ways,
|
|
|
|
std::vector<boost::optional<InputRestrictionContainer>> &resulting_restrictions)
|
2016-10-25 16:22:06 -04:00
|
|
|
{
|
2017-06-08 17:04:48 -04:00
|
|
|
ExtractionNode result_node;
|
|
|
|
ExtractionWay result_way;
|
|
|
|
std::vector<InputRestrictionContainer> result_res;
|
|
|
|
auto &local_context = this->GetSol2Context();
|
|
|
|
|
|
|
|
for (auto entity = buffer.cbegin(), end = buffer.cend(); entity != end; ++entity)
|
|
|
|
{
|
|
|
|
switch (entity->type())
|
|
|
|
{
|
|
|
|
case osmium::item_type::node:
|
|
|
|
result_node.clear();
|
|
|
|
if (local_context.has_node_function &&
|
|
|
|
(!static_cast<const osmium::Node &>(*entity).tags().empty() ||
|
|
|
|
local_context.properties.call_tagless_node_function))
|
|
|
|
{
|
|
|
|
local_context.ProcessNode(static_cast<const osmium::Node &>(*entity), result_node);
|
|
|
|
}
|
|
|
|
resulting_nodes.push_back(std::pair<const osmium::Node &, ExtractionNode>(
|
|
|
|
static_cast<const osmium::Node &>(*entity), std::move(result_node)));
|
|
|
|
break;
|
|
|
|
case osmium::item_type::way:
|
|
|
|
result_way.clear();
|
|
|
|
if (local_context.has_way_function)
|
2016-10-25 16:22:06 -04:00
|
|
|
{
|
2017-06-08 17:04:48 -04:00
|
|
|
local_context.ProcessWay(static_cast<const osmium::Way &>(*entity), result_way);
|
2016-10-25 16:22:06 -04:00
|
|
|
}
|
2017-06-08 17:04:48 -04:00
|
|
|
resulting_ways.push_back(std::pair<const osmium::Way &, ExtractionWay>(
|
|
|
|
static_cast<const osmium::Way &>(*entity), std::move(result_way)));
|
|
|
|
break;
|
|
|
|
case osmium::item_type::relation:
|
|
|
|
result_res.clear();
|
|
|
|
result_res =
|
|
|
|
restriction_parser.TryParse(static_cast<const osmium::Relation &>(*entity));
|
|
|
|
for (const InputRestrictionContainer &r : result_res)
|
|
|
|
{
|
|
|
|
resulting_restrictions.push_back(r);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
2016-10-25 16:22:06 -04:00
|
|
|
}
|
|
|
|
|
2017-05-18 08:27:28 -04:00
|
|
|
std::vector<std::string>
|
|
|
|
Sol2ScriptingEnvironment::GetStringListFromFunction(const std::string &function_name)
|
2016-10-25 16:22:06 -04:00
|
|
|
{
|
|
|
|
auto &context = GetSol2Context();
|
2016-10-19 23:02:41 -04:00
|
|
|
BOOST_ASSERT(context.state.lua_state() != nullptr);
|
2017-05-18 08:27:28 -04:00
|
|
|
std::vector<std::string> strings;
|
|
|
|
sol::function function = context.state[function_name];
|
|
|
|
if (function.valid())
|
2016-10-19 23:02:41 -04:00
|
|
|
{
|
2017-05-18 08:27:28 -04:00
|
|
|
function(strings);
|
2016-10-19 23:02:41 -04:00
|
|
|
}
|
2017-05-18 08:27:28 -04:00
|
|
|
return strings;
|
2016-10-25 16:22:06 -04:00
|
|
|
}
|
|
|
|
|
2017-05-18 08:27:28 -04:00
|
|
|
std::vector<std::string>
|
|
|
|
Sol2ScriptingEnvironment::GetStringListFromTable(const std::string &table_name)
|
2016-10-25 16:22:06 -04:00
|
|
|
{
|
|
|
|
auto &context = GetSol2Context();
|
2016-10-19 23:02:41 -04:00
|
|
|
BOOST_ASSERT(context.state.lua_state() != nullptr);
|
2017-05-18 08:27:28 -04:00
|
|
|
std::vector<std::string> strings;
|
|
|
|
sol::table table = context.profile_table[table_name];
|
|
|
|
if (table.valid())
|
2016-10-19 23:02:41 -04:00
|
|
|
{
|
2017-05-18 08:27:28 -04:00
|
|
|
for (auto &&pair : table)
|
|
|
|
{
|
|
|
|
strings.push_back(pair.second.as<std::string>());
|
|
|
|
};
|
2016-10-19 23:02:41 -04:00
|
|
|
}
|
2017-05-18 08:27:28 -04:00
|
|
|
return strings;
|
2016-10-25 16:22:06 -04:00
|
|
|
}
|
|
|
|
|
2017-05-18 08:27:28 -04:00
|
|
|
std::vector<std::string> Sol2ScriptingEnvironment::GetNameSuffixList()
|
2016-10-25 16:22:06 -04:00
|
|
|
{
|
|
|
|
auto &context = GetSol2Context();
|
2017-05-18 08:27:28 -04:00
|
|
|
switch (context.api_version)
|
|
|
|
{
|
|
|
|
case 2:
|
|
|
|
return Sol2ScriptingEnvironment::GetStringListFromTable("suffix_list");
|
|
|
|
case 1:
|
|
|
|
return Sol2ScriptingEnvironment::GetStringListFromFunction("get_name_suffix_list");
|
|
|
|
default:
|
|
|
|
return {};
|
|
|
|
}
|
|
|
|
}
|
2016-10-25 16:22:06 -04:00
|
|
|
|
2017-05-18 08:27:28 -04:00
|
|
|
std::vector<std::string> Sol2ScriptingEnvironment::GetRestrictions()
|
|
|
|
{
|
|
|
|
auto &context = GetSol2Context();
|
|
|
|
switch (context.api_version)
|
2016-10-19 23:02:41 -04:00
|
|
|
{
|
2017-05-18 08:27:28 -04:00
|
|
|
case 2:
|
|
|
|
return Sol2ScriptingEnvironment::GetStringListFromTable("restrictions");
|
|
|
|
case 1:
|
|
|
|
return Sol2ScriptingEnvironment::GetStringListFromFunction("get_restrictions");
|
|
|
|
default:
|
|
|
|
return {};
|
2016-10-19 23:02:41 -04:00
|
|
|
}
|
2016-10-25 16:22:06 -04:00
|
|
|
}
|
|
|
|
|
2016-05-12 12:50:10 -04:00
|
|
|
void Sol2ScriptingEnvironment::ProcessTurn(ExtractionTurn &turn)
|
2016-10-25 16:22:06 -04:00
|
|
|
{
|
|
|
|
auto &context = GetSol2Context();
|
2016-10-19 23:02:41 -04:00
|
|
|
|
2016-05-12 12:50:10 -04:00
|
|
|
switch (context.api_version)
|
2016-10-19 23:02:41 -04:00
|
|
|
{
|
2017-05-18 08:27:28 -04:00
|
|
|
case 2:
|
|
|
|
if (context.has_turn_penalty_function)
|
|
|
|
{
|
|
|
|
context.turn_function(context.profile_table, turn);
|
|
|
|
|
|
|
|
// Turn weight falls back to the duration value in deciseconds
|
|
|
|
// or uses the extracted unit-less weight value
|
|
|
|
if (context.properties.fallback_to_duration)
|
|
|
|
turn.weight = turn.duration;
|
|
|
|
else
|
|
|
|
// cap turn weight to max turn weight, which depend on weight precision
|
|
|
|
turn.weight = std::min(turn.weight, context.properties.GetMaxTurnWeight());
|
|
|
|
}
|
|
|
|
|
|
|
|
break;
|
2016-05-12 12:50:10 -04:00
|
|
|
case 1:
|
|
|
|
if (context.has_turn_penalty_function)
|
|
|
|
{
|
2017-06-12 12:40:17 -04:00
|
|
|
context.turn_function(turn);
|
2016-05-12 12:50:10 -04:00
|
|
|
|
|
|
|
// Turn weight falls back to the duration value in deciseconds
|
|
|
|
// or uses the extracted unit-less weight value
|
|
|
|
if (context.properties.fallback_to_duration)
|
|
|
|
turn.weight = turn.duration;
|
|
|
|
}
|
|
|
|
|
|
|
|
break;
|
|
|
|
case 0:
|
|
|
|
if (context.has_turn_penalty_function)
|
|
|
|
{
|
|
|
|
if (turn.turn_type != guidance::TurnType::NoTurn)
|
|
|
|
{
|
|
|
|
// Get turn duration and convert deci-seconds to seconds
|
2017-06-12 12:40:17 -04:00
|
|
|
turn.duration = static_cast<double>(context.turn_function(turn.angle)) / 10.;
|
2016-05-12 12:50:10 -04:00
|
|
|
BOOST_ASSERT(turn.weight == 0);
|
2016-10-19 23:02:41 -04:00
|
|
|
|
2016-05-12 12:50:10 -04:00
|
|
|
// add U-turn penalty
|
|
|
|
if (turn.direction_modifier == guidance::DirectionModifier::UTurn)
|
|
|
|
turn.duration += context.properties.GetUturnPenalty();
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
// Use zero turn penalty if it is not an actual turn. This heuristic is necessary
|
|
|
|
// since OSRM cannot handle looping roads/parallel roads
|
|
|
|
turn.duration = 0.;
|
|
|
|
}
|
|
|
|
}
|
2016-10-19 23:02:41 -04:00
|
|
|
|
2016-05-12 12:50:10 -04:00
|
|
|
// Add traffic light penalty, back-compatibility of api_version=0
|
|
|
|
if (turn.has_traffic_light)
|
|
|
|
turn.duration += context.properties.GetTrafficSignalPenalty();
|
2016-10-19 23:02:41 -04:00
|
|
|
|
2016-05-12 12:50:10 -04:00
|
|
|
// Turn weight falls back to the duration value in deciseconds
|
|
|
|
turn.weight = turn.duration;
|
|
|
|
break;
|
|
|
|
}
|
2016-10-25 16:22:06 -04:00
|
|
|
}
|
|
|
|
|
2016-05-12 12:50:10 -04:00
|
|
|
void Sol2ScriptingEnvironment::ProcessSegment(ExtractionSegment &segment)
|
2016-10-25 16:22:06 -04:00
|
|
|
{
|
|
|
|
auto &context = GetSol2Context();
|
2016-10-19 23:02:41 -04:00
|
|
|
|
2016-05-12 12:50:10 -04:00
|
|
|
if (context.has_segment_function)
|
2016-10-19 23:02:41 -04:00
|
|
|
{
|
2016-05-12 12:50:10 -04:00
|
|
|
switch (context.api_version)
|
|
|
|
{
|
2017-05-18 08:27:28 -04:00
|
|
|
case 2:
|
|
|
|
context.segment_function(context.profile_table, segment);
|
|
|
|
break;
|
2016-05-12 12:50:10 -04:00
|
|
|
case 1:
|
2017-06-12 12:40:17 -04:00
|
|
|
context.segment_function(segment);
|
2016-05-12 12:50:10 -04:00
|
|
|
break;
|
|
|
|
case 0:
|
2017-06-12 12:40:17 -04:00
|
|
|
context.segment_function(
|
|
|
|
segment.source, segment.target, segment.distance, segment.duration);
|
2016-05-12 12:50:10 -04:00
|
|
|
segment.weight = segment.duration; // back-compatibility fallback to duration
|
|
|
|
break;
|
|
|
|
}
|
2016-10-19 23:02:41 -04:00
|
|
|
}
|
2016-10-25 16:22:06 -04:00
|
|
|
}
|
|
|
|
|
2016-12-07 17:02:09 -05:00
|
|
|
void LuaScriptingContext::ProcessNode(const osmium::Node &node, ExtractionNode &result)
|
2016-10-25 16:22:06 -04:00
|
|
|
{
|
2016-10-19 23:02:41 -04:00
|
|
|
BOOST_ASSERT(state.lua_state() != nullptr);
|
|
|
|
|
2017-05-18 08:27:28 -04:00
|
|
|
switch (api_version)
|
|
|
|
{
|
|
|
|
case 2:
|
|
|
|
node_function(profile_table, node, result);
|
|
|
|
break;
|
|
|
|
case 1:
|
|
|
|
case 0:
|
|
|
|
node_function(node, result);
|
|
|
|
break;
|
|
|
|
}
|
2016-10-25 16:22:06 -04:00
|
|
|
}
|
|
|
|
|
2016-12-07 17:02:09 -05:00
|
|
|
void LuaScriptingContext::ProcessWay(const osmium::Way &way, ExtractionWay &result)
|
2016-10-25 16:22:06 -04:00
|
|
|
{
|
2016-10-19 23:02:41 -04:00
|
|
|
BOOST_ASSERT(state.lua_state() != nullptr);
|
|
|
|
|
2017-05-18 08:27:28 -04:00
|
|
|
switch (api_version)
|
|
|
|
{
|
|
|
|
case 2:
|
|
|
|
way_function(profile_table, way, result);
|
|
|
|
break;
|
|
|
|
case 1:
|
|
|
|
case 0:
|
|
|
|
way_function(way, result);
|
|
|
|
break;
|
|
|
|
}
|
2016-10-25 16:22:06 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|