profiles api v2

This commit is contained in:
Emil Tin
2017-05-18 14:27:28 +02:00
committed by Patrick Niklaus
parent 5ece65cade
commit e413b25cd9
41 changed files with 1858 additions and 1208 deletions
+235 -244
View File
@@ -1,199 +1,196 @@
api_version = 1
-- Bicycle profile
local find_access_tag = require("lib/access").find_access_tag
local Set = require('lib/set')
local Sequence = require('lib/sequence')
local Handlers = require("lib/handlers")
local next = next -- bind to local for speed
local limit = require("lib/maxspeed").limit
-- these need to be global because they are accesed externaly
properties.max_speed_for_map_matching = 110/3.6 -- kmph -> m/s
properties.use_turn_restrictions = false
properties.continue_straight_at_waypoint = false
properties.weight_name = 'duration'
--properties.weight_name = 'cyclability'
api_version = 2
-- Set to true if you need to call the node_function for every node.
-- Generally can be left as false to avoid unnecessary Lua calls
-- (which slow down pre-processing).
properties.call_tagless_node_function = false
Set = require('lib/set')
Sequence = require('lib/sequence')
Handlers = require("lib/way_handlers")
find_access_tag = require("lib/access").find_access_tag
limit = require("lib/maxspeed").limit
function setup()
local default_speed = 15
local walking_speed = 6
local default_speed = 15
local walking_speed = 6
return {
properties = {
u_turn_penalty = 20,
traffic_light_penalty = 2,
--weight_name = 'cyclability',
weight_name = 'duration',
process_call_tagless_node = false,
max_speed_for_map_matching = 110/3.6, -- kmph -> m/s
use_turn_restrictions = false,
continue_straight_at_waypoint = false
},
local profile = {
default_mode = mode.cycling,
default_speed = 15,
oneway_handling = true,
traffic_light_penalty = 2,
u_turn_penalty = 20,
turn_penalty = 6,
turn_bias = 1.4,
use_public_transport = true,
default_mode = mode.cycling,
default_speed = default_speed,
walking_speed = walking_speed,
oneway_handling = true,
turn_penalty = 6,
turn_bias = 1.4,
use_public_transport = true,
allowed_start_modes = Set {
mode.cycling,
mode.pushing_bike
},
allowed_start_modes = Set {
mode.cycling,
mode.pushing_bike
},
barrier_whitelist = Set {
'sump_buster',
'bus_trap',
'cycle_barrier',
'bollard',
'entrance',
'cattle_grid',
'border_control',
'toll_booth',
'sally_port',
'gate',
'no',
'block'
},
barrier_whitelist = Set {
'sump_buster',
'bus_trap',
'cycle_barrier',
'bollard',
'entrance',
'cattle_grid',
'border_control',
'toll_booth',
'sally_port',
'gate',
'no',
'block'
},
access_tag_whitelist = Set {
'yes',
'permissive',
'designated'
},
access_tag_whitelist = Set {
'yes',
'permissive',
'designated'
},
access_tag_blacklist = Set {
'no',
'private',
'agricultural',
'forestry',
'delivery'
},
access_tag_blacklist = Set {
'no',
'private',
'agricultural',
'forestry',
'delivery'
},
restricted_access_tag_list = Set { },
restricted_access_tag_list = Set { },
restricted_highway_whitelist = Set { },
restricted_highway_whitelist = Set { },
access_tags_hierarchy = Sequence {
'bicycle',
'vehicle',
'access'
},
access_tags_hierarchy = Sequence {
'bicycle',
'vehicle',
'access'
},
restrictions = Set {
'bicycle'
},
restrictions = Set {
'bicycle'
},
cycleway_tags = Set {
'track',
'lane',
'opposite',
'opposite_lane',
'opposite_track',
'share_busway',
'sharrow',
'shared',
'shared_lane'
},
cycleway_tags = Set {
'track',
'lane',
'opposite',
'opposite_lane',
'opposite_track',
'share_busway',
'sharrow',
'shared',
'shared_lane'
},
-- reduce the driving speed by 30% for unsafe roads
-- only used for cyclability metric
unsafe_highway_list = {
primary = 0.7,
secondary = 0.75,
tertiary = 0.8,
primary_link = 0.7,
secondary_link = 0.75,
tertiary_link = 0.8,
},
-- reduce the driving speed by 30% for unsafe roads
-- only used for cyclability metric
unsafe_highway_list = {
primary = 0.7,
secondary = 0.75,
tertiary = 0.8,
primary_link = 0.7,
secondary_link = 0.75,
tertiary_link = 0.8,
},
service_penalties = {
alley = 0.5,
},
service_penalties = {
alley = 0.5,
},
bicycle_speeds = {
cycleway = default_speed,
primary = default_speed,
primary_link = default_speed,
secondary = default_speed,
secondary_link = default_speed,
tertiary = default_speed,
tertiary_link = default_speed,
residential = default_speed,
unclassified = default_speed,
living_street = default_speed,
road = default_speed,
service = default_speed,
track = 12,
path = 12
},
bicycle_speeds = {
cycleway = default_speed,
primary = default_speed,
primary_link = default_speed,
secondary = default_speed,
secondary_link = default_speed,
tertiary = default_speed,
tertiary_link = default_speed,
residential = default_speed,
unclassified = default_speed,
living_street = default_speed,
road = default_speed,
service = default_speed,
track = 12,
path = 12
},
pedestrian_speeds = {
footway = walking_speed,
pedestrian = walking_speed,
steps = 2
},
pedestrian_speeds = {
footway = walking_speed,
pedestrian = walking_speed,
steps = 2
},
railway_speeds = {
train = 10,
railway = 10,
subway = 10,
light_rail = 10,
monorail = 10,
tram = 10
},
railway_speeds = {
train = 10,
railway = 10,
subway = 10,
light_rail = 10,
monorail = 10,
tram = 10
},
platform_speeds = {
platform = walking_speed
},
platform_speeds = {
platform = walking_speed
},
amenity_speeds = {
parking = 10,
parking_entrance = 10
},
amenity_speeds = {
parking = 10,
parking_entrance = 10
},
man_made_speeds = {
pier = walking_speed
},
man_made_speeds = {
pier = walking_speed
},
route_speeds = {
ferry = 5
},
route_speeds = {
ferry = 5
},
bridge_speeds = {
movable = 5
},
bridge_speeds = {
movable = 5
},
surface_speeds = {
asphalt = default_speed,
["cobblestone:flattened"] = 10,
paving_stones = 10,
compacted = 10,
cobblestone = 6,
unpaved = 6,
fine_gravel = 6,
gravel = 6,
pebblestone = 6,
ground = 6,
dirt = 6,
earth = 6,
grass = 6,
mud = 3,
sand = 3,
sett = 10
},
surface_speeds = {
asphalt = default_speed,
["cobblestone:flattened"] = 10,
paving_stones = 10,
compacted = 10,
cobblestone = 6,
unpaved = 6,
fine_gravel = 6,
gravel = 6,
pebblestone = 6,
ground = 6,
dirt = 6,
earth = 6,
grass = 6,
mud = 3,
sand = 3,
sett = 10
},
tracktype_speeds = {
},
tracktype_speeds = {
},
smoothness_speeds = {
},
smoothness_speeds = {
},
avoid = Set {
'impassable',
'construction',
'proposed'
avoid = Set {
'impassable',
'construction'
}
}
}
end
local function parse_maxspeed(source)
if not source then
@@ -209,13 +206,7 @@ local function parse_maxspeed(source)
return n
end
function get_restrictions(vector)
for i,v in ipairs(profile.restrictions) do
vector:Add(v)
end
end
function node_function (node, result)
function process_node (profile, node, result)
-- parse access and barrier tags
local highway = node:get_value_by_key("highway")
local is_crossing = highway and highway == "crossing"
@@ -243,41 +234,8 @@ function node_function (node, result)
end
end
function way_function (way, result)
-- the intial filtering of ways based on presence of tags
-- affects processing times significantly, because all ways
-- have to be checked.
-- to increase performance, prefetching and intial tag check
-- is done in directly instead of via a handler.
-- in general we should try to abort as soon as
-- possible if the way is not routable, to avoid doing
-- unnecessary work. this implies we should check things that
-- commonly forbids access early, and handle edge cases later.
-- data table for storing intermediate values during processing
local data = {
-- prefetch tags
highway = way:get_value_by_key('highway'),
}
local handlers = Sequence {
-- set the default mode for this profile. if can be changed later
-- in case it turns we're e.g. on a ferry
'handle_default_mode',
-- check various tags that could indicate that the way is not
-- routable. this includes things like status=impassable,
-- toll=yes and oneway=reversible
'handle_blocked_ways',
}
if Handlers.run(handlers,way,result,data,profile) == false then
return
end
-- initial routability check, filters out buildings, boundaries, etc
function handle_bicycle_tags(profile,way,result,data)
-- initial routability check, filters out buildings, boundaries, etc
local route = way:get_value_by_key("route")
local man_made = way:get_value_by_key("man_made")
local railway = way:get_value_by_key("railway")
@@ -293,13 +251,13 @@ function way_function (way, result)
(not public_transport or public_transport=='') and
(not bridge or bridge=='')
then
return
return false
end
-- access
local access = find_access_tag(way, profile.access_tags_hierarchy)
if access and profile.access_tag_blacklist[access] then
return
return false
end
-- other tags
@@ -371,8 +329,8 @@ function way_function (way, result)
way_type_allows_pushing = true
elseif access and profile.access_tag_whitelist[access] then
-- unknown way, but valid access tag
result.forward_speed = default_speed
result.backward_speed = default_speed
result.forward_speed = profile.default_speed
result.backward_speed = profile.default_speed
way_type_allows_pushing = true
end
@@ -447,18 +405,18 @@ function way_function (way, result)
push_backward_speed = profile.man_made_speeds[man_made]
else
if foot == 'yes' then
push_forward_speed = walking_speed
push_forward_speed = profile.walking_speed
if not implied_oneway then
push_backward_speed = walking_speed
push_backward_speed = profile.walking_speed
end
elseif foot_forward == 'yes' then
push_forward_speed = walking_speed
push_forward_speed = profile.walking_speed
elseif foot_backward == 'yes' then
push_backward_speed = walking_speed
push_backward_speed = profile.walking_speed
elseif way_type_allows_pushing then
push_forward_speed = walking_speed
push_forward_speed = profile.walking_speed
if not implied_oneway then
push_backward_speed = walking_speed
push_backward_speed = profile.walking_speed
end
end
end
@@ -481,8 +439,8 @@ function way_function (way, result)
if bicycle == "dismount" then
result.forward_mode = mode.pushing_bike
result.backward_mode = mode.pushing_bike
result.forward_speed = walking_speed
result.backward_speed = walking_speed
result.forward_speed = profile.walking_speed
result.backward_speed = profile.walking_speed
end
@@ -502,7 +460,7 @@ function way_function (way, result)
-- convert duration into cyclability
if properties.weight_name == 'cyclability' then
if profile.properties.weight_name == 'cyclability' then
local safety_penalty = profile.unsafe_highway_list[data.highway] or 1.
local is_unsafe = safety_penalty < 1
local forward_is_unsafe = is_unsafe and not has_cycleway_right
@@ -534,29 +492,59 @@ function way_function (way, result)
result.weight = result.duration / forward_penalty
end
end
end
function process_way (profile, way, result)
-- the initial filtering of ways based on presence of tags
-- affects processing times significantly, because all ways
-- have to be checked.
-- to increase performance, prefetching and initial tag check
-- is done directly instead of via a handler.
local handlers = Sequence {
-- compute speed taking into account way type, maxspeed tags, etc.
'handle_surface',
-- in general we should try to abort as soon as
-- possible if the way is not routable, to avoid doing
-- unnecessary work. this implies we should check things that
-- commonly forbids access early, and handle edge cases later.
-- handle turn lanes and road classification, used for guidance
'handle_classification',
-- data table for storing intermediate values during processing
-- handle various other flags
'handle_roundabouts',
-- handle allowed start/end modes
'handle_startpoint',
-- set name, ref and pronunciation
'handle_names'
local data = {
-- prefetch tags
highway = way:get_value_by_key('highway'),
}
Handlers.run(handlers,way,result,data,profile)
local handlers = Sequence {
-- set the default mode for this profile. if can be changed later
-- in case it turns we're e.g. on a ferry
WayHandlers.default_mode,
-- check various tags that could indicate that the way is not
-- routable. this includes things like status=impassable,
-- toll=yes and oneway=reversible
WayHandlers.blocked_ways,
-- our main handler
handle_bicycle_tags,
-- compute speed taking into account way type, maxspeed tags, etc.
WayHandlers.surface,
-- handle turn lanes and road classification, used for guidance
WayHandlers.classification,
-- handle allowed start/end modes
WayHandlers.startpoint,
-- handle roundabouts
WayHandlers.roundabouts,
-- set name, ref and pronunciation
WayHandlers.names
}
WayHandlers.run(profile,way,result,data,handlers)
end
function turn_function(turn)
function process_turn(profile, turn)
-- compute turn penalty as angle^2, with a left/right bias
local normalized_angle = turn.angle / 90.0
if normalized_angle >= 0.0 then
@@ -566,17 +554,20 @@ function turn_function(turn)
end
if turn.direction_modifier == direction_modifier.uturn then
turn.duration = turn.duration + profile.u_turn_penalty
turn.duration = turn.duration + profile.properties.u_turn_penalty
end
if turn.has_traffic_light then
turn.duration = turn.duration + profile.traffic_light_penalty
turn.duration = turn.duration + profile.properties.traffic_light_penalty
end
if properties.weight_name == 'cyclability' then
turn.weight = turn.duration
-- penalize turns from non-local access only segments onto local access only tags
if not turn.source_restricted and turn.target_restricted then
turn.weight = turn.weight + 3000
end
if profile.properties.weight_name == 'cyclability' then
turn.weight = turn.duration
end
end
return {
setup = setup,
process_way = process_way,
process_node = process_node,
process_turn = process_turn
}
+278 -285
View File
@@ -1,282 +1,268 @@
-- Car profile
api_version = 1
api_version = 2
local find_access_tag = require("lib/access").find_access_tag
local Set = require('lib/set')
local Sequence = require('lib/sequence')
local Handlers = require("lib/handlers")
local next = next -- bind to local for speed
Set = require('lib/set')
Sequence = require('lib/sequence')
Handlers = require("lib/way_handlers")
find_access_tag = require("lib/access").find_access_tag
limit = require("lib/maxspeed").limit
-- set profile properties
properties.max_speed_for_map_matching = 180/3.6 -- 180kmph -> m/s
properties.use_turn_restrictions = true
properties.continue_straight_at_waypoint = true
properties.left_hand_driving = false
-- For routing based on duration, but weighted for preferring certain roads
properties.weight_name = 'routability'
-- For shortest duration without penalties for accessibility
--properties.weight_name = 'duration'
-- For shortest distance without penalties for accessibility
--properties.weight_name = 'distance'
function setup()
local use_left_hand_driving = false
return {
properties = {
max_speed_for_map_matching = 180/3.6, -- 180kmph -> m/s
left_hand_driving = use_left_hand_driving,
-- For routing based on duration, but weighted for preferring certain roads
weight_name = 'routability',
-- For shortest duration without penalties for accessibility
-- weight_name = 'duration',
-- For shortest distance without penalties for accessibility
-- weight_name = 'distance',
process_call_tagless_node = false,
u_turn_penalty = 20,
continue_straight_at_waypoint = true,
use_turn_restrictions = true,
traffic_light_penalty = 2,
},
default_mode = mode.driving,
default_speed = 10,
oneway_handling = true,
side_road_multiplier = 0.8,
turn_penalty = 7.5,
speed_reduction = 0.8,
-- Set to true if you need to call the node_function for every node.
-- Generally can be left as false to avoid unnecessary Lua calls
-- (which slow down pre-processing).
properties.call_tagless_node_function = false
-- Note: this biases right-side driving.
-- Should be inverted for left-driving countries.
turn_bias = use_left_hand_driving and 1/1.075 or 1.075,
-- a list of suffixes to suppress in name change instructions
suffix_list = {
'N', 'NE', 'E', 'SE', 'S', 'SW', 'W', 'NW', 'North', 'South', 'West', 'East'
},
local profile = {
default_mode = mode.driving,
default_speed = 10,
oneway_handling = true,
barrier_whitelist = Set {
'cattle_grid',
'border_control',
'checkpoint',
'toll_booth',
'sally_port',
'gate',
'lift_gate',
'no',
'entrance'
},
side_road_multiplier = 0.8,
turn_penalty = 7.5,
speed_reduction = 0.8,
traffic_light_penalty = 2,
u_turn_penalty = 20,
access_tag_whitelist = Set {
'yes',
'motorcar',
'motor_vehicle',
'vehicle',
'permissive',
'designated',
'hov'
},
-- Note: this biases right-side driving.
-- Should be inverted for left-driving countries.
turn_bias = properties.left_hand_driving and 1/1.075 or 1.075,
access_tag_blacklist = Set {
'no',
'agricultural',
'forestry',
'emergency',
'psv',
'customers',
'private',
'delivery',
'destination'
},
-- a list of suffixes to suppress in name change instructions
suffix_list = {
'N', 'NE', 'E', 'SE', 'S', 'SW', 'W', 'NW', 'North', 'South', 'West', 'East'
},
restricted_access_tag_list = Set {
'private',
'delivery',
'destination',
'customers',
},
barrier_whitelist = Set {
'cattle_grid',
'border_control',
'checkpoint',
'toll_booth',
'sally_port',
'gate',
'lift_gate',
'no',
'entrance'
},
access_tags_hierarchy = Sequence {
'motorcar',
'motor_vehicle',
'vehicle',
'access'
},
access_tag_whitelist = Set {
'yes',
'motorcar',
'motor_vehicle',
'vehicle',
'permissive',
'designated',
'hov'
},
service_tag_forbidden = Set {
'emergency_access'
},
access_tag_blacklist = Set {
'no',
'agricultural',
'forestry',
'emergency',
'psv',
'customers',
'private',
'delivery',
'destination'
},
restrictions = Sequence {
'motorcar',
'motor_vehicle',
'vehicle'
},
restricted_access_tag_list = Set {
'private',
'delivery',
'destination',
'customers',
},
avoid = Set {
'area',
-- 'toll', -- uncomment this to avoid tolls
'reversible',
'impassable',
'hov_lanes',
'steps',
'construction',
'proposed'
},
access_tags_hierarchy = Sequence {
'motorcar',
'motor_vehicle',
'vehicle',
'access'
},
speeds = Sequence {
highway = {
motorway = 90,
motorway_link = 45,
trunk = 85,
trunk_link = 40,
primary = 65,
primary_link = 30,
secondary = 55,
secondary_link = 25,
tertiary = 40,
tertiary_link = 20,
unclassified = 25,
residential = 25,
living_street = 10,
service = 15
}
},
service_tag_forbidden = Set {
'emergency_access'
},
service_penalties = {
alley = 0.5,
parking = 0.5,
parking_aisle = 0.5,
driveway = 0.5,
["drive-through"] = 0.5,
["drive-thru"] = 0.5
},
restrictions = Sequence {
'motorcar',
'motor_vehicle',
'vehicle'
},
restricted_highway_whitelist = Set {
'motorway',
'motorway_link',
'trunk',
'trunk_link',
'primary',
'primary_link',
'secondary',
'secondary_link',
'tertiary',
'tertiary_link',
'residential',
'living_street',
},
avoid = Set {
'area',
-- 'toll', -- uncomment this to avoid tolls
'reversible',
'impassable',
'hov_lanes',
'steps',
'construction',
'proposed'
},
route_speeds = {
ferry = 5,
shuttle_train = 10
},
speeds = Sequence {
highway = {
motorway = 90,
motorway_link = 45,
trunk = 85,
trunk_link = 40,
primary = 65,
primary_link = 30,
secondary = 55,
secondary_link = 25,
tertiary = 40,
tertiary_link = 20,
unclassified = 25,
residential = 25,
living_street = 10,
service = 15
bridge_speeds = {
movable = 5
},
-- surface/trackype/smoothness
-- values were estimated from looking at the photos at the relevant wiki pages
-- max speed for surfaces
surface_speeds = {
asphalt = nil, -- nil mean no limit. removing the line has the same effect
concrete = nil,
["concrete:plates"] = nil,
["concrete:lanes"] = nil,
paved = nil,
cement = 80,
compacted = 80,
fine_gravel = 80,
paving_stones = 60,
metal = 60,
bricks = 60,
grass = 40,
wood = 40,
sett = 40,
grass_paver = 40,
gravel = 40,
unpaved = 40,
ground = 40,
dirt = 40,
pebblestone = 40,
tartan = 40,
cobblestone = 30,
clay = 30,
earth = 20,
stone = 20,
rocky = 20,
sand = 20,
mud = 10
},
-- max speed for tracktypes
tracktype_speeds = {
grade1 = 60,
grade2 = 40,
grade3 = 30,
grade4 = 25,
grade5 = 20
},
-- max speed for smoothnesses
smoothness_speeds = {
intermediate = 80,
bad = 40,
very_bad = 20,
horrible = 10,
very_horrible = 5,
impassable = 0
},
-- http://wiki.openstreetmap.org/wiki/Speed_limits
maxspeed_table_default = {
urban = 50,
rural = 90,
trunk = 110,
motorway = 130
},
-- List only exceptions
maxspeed_table = {
["ch:rural"] = 80,
["ch:trunk"] = 100,
["ch:motorway"] = 120,
["de:living_street"] = 7,
["ru:living_street"] = 20,
["ru:urban"] = 60,
["ua:urban"] = 60,
["at:rural"] = 100,
["de:rural"] = 100,
["at:trunk"] = 100,
["cz:trunk"] = 0,
["ro:trunk"] = 100,
["cz:motorway"] = 0,
["de:motorway"] = 0,
["ru:motorway"] = 110,
["gb:nsl_single"] = (60*1609)/1000,
["gb:nsl_dual"] = (70*1609)/1000,
["gb:motorway"] = (70*1609)/1000,
["uk:nsl_single"] = (60*1609)/1000,
["uk:nsl_dual"] = (70*1609)/1000,
["uk:motorway"] = (70*1609)/1000,
["nl:rural"] = 80,
["nl:trunk"] = 100,
["none"] = 140
}
},
service_penalties = {
alley = 0.5,
parking = 0.5,
parking_aisle = 0.5,
driveway = 0.5,
["drive-through"] = 0.5,
["drive-thru"] = 0.5
},
restricted_highway_whitelist = Set {
'motorway',
'motorway_link',
'trunk',
'trunk_link',
'primary',
'primary_link',
'secondary',
'secondary_link',
'tertiary',
'tertiary_link',
'residential',
'living_street',
},
route_speeds = {
ferry = 5,
shuttle_train = 10
},
bridge_speeds = {
movable = 5
},
-- surface/trackype/smoothness
-- values were estimated from looking at the photos at the relevant wiki pages
-- max speed for surfaces
surface_speeds = {
asphalt = nil, -- nil mean no limit. removing the line has the same effect
concrete = nil,
["concrete:plates"] = nil,
["concrete:lanes"] = nil,
paved = nil,
cement = 80,
compacted = 80,
fine_gravel = 80,
paving_stones = 60,
metal = 60,
bricks = 60,
grass = 40,
wood = 40,
sett = 40,
grass_paver = 40,
gravel = 40,
unpaved = 40,
ground = 40,
dirt = 40,
pebblestone = 40,
tartan = 40,
cobblestone = 30,
clay = 30,
earth = 20,
stone = 20,
rocky = 20,
sand = 20,
mud = 10
},
-- max speed for tracktypes
tracktype_speeds = {
grade1 = 60,
grade2 = 40,
grade3 = 30,
grade4 = 25,
grade5 = 20
},
-- max speed for smoothnesses
smoothness_speeds = {
intermediate = 80,
bad = 40,
very_bad = 20,
horrible = 10,
very_horrible = 5,
impassable = 0
},
-- http://wiki.openstreetmap.org/wiki/Speed_limits
maxspeed_table_default = {
urban = 50,
rural = 90,
trunk = 110,
motorway = 130
},
-- List only exceptions
maxspeed_table = {
["ch:rural"] = 80,
["ch:trunk"] = 100,
["ch:motorway"] = 120,
["de:living_street"] = 7,
["ru:living_street"] = 20,
["ru:urban"] = 60,
["ua:urban"] = 60,
["at:rural"] = 100,
["de:rural"] = 100,
["at:trunk"] = 100,
["cz:trunk"] = 0,
["ro:trunk"] = 100,
["cz:motorway"] = 0,
["de:motorway"] = 0,
["ru:motorway"] = 110,
["gb:nsl_single"] = (60*1609)/1000,
["gb:nsl_dual"] = (70*1609)/1000,
["gb:motorway"] = (70*1609)/1000,
["uk:nsl_single"] = (60*1609)/1000,
["uk:nsl_dual"] = (70*1609)/1000,
["uk:motorway"] = (70*1609)/1000,
["nl:rural"] = 80,
["nl:trunk"] = 100,
["none"] = 140
}
}
function get_name_suffix_list(vector)
for index,suffix in ipairs(profile.suffix_list) do
vector:Add(suffix)
end
end
function get_restrictions(vector)
for i,v in ipairs(profile.restrictions) do
vector:Add(v)
end
end
function node_function (node, result)
function process_node (profile, node, result)
-- parse access and barrier tags
local access = find_access_tag(node, profile.access_tags_hierarchy)
if access then
@@ -303,7 +289,7 @@ function node_function (node, result)
end
end
function way_function(way, result)
function process_way(profile, way, result)
-- the intial filtering of ways based on presence of tags
-- affects processing times significantly, because all ways
-- have to be checked.
@@ -335,61 +321,61 @@ function way_function(way, result)
handlers = Sequence {
-- set the default mode for this profile. if can be changed later
-- in case it turns we're e.g. on a ferry
'handle_default_mode',
WayHandlers.default_mode,
-- check various tags that could indicate that the way is not
-- routable. this includes things like status=impassable,
-- toll=yes and oneway=reversible
'handle_blocked_ways',
WayHandlers.blocked_ways,
-- determine access status by checking our hierarchy of
-- access tags, e.g: motorcar, motor_vehicle, vehicle
'handle_access',
WayHandlers.access,
-- check whether forward/backward directions are routable
'handle_oneway',
WayHandlers.oneway,
-- check a road's destination
'handle_destinations',
WayHandlers.destinations,
-- check whether we're using a special transport mode
'handle_ferries',
'handle_movables',
WayHandlers.ferries,
WayHandlers.movables,
-- handle service road restrictions
'handle_service',
WayHandlers.service,
-- handle hov
'handle_hov',
WayHandlers.hov,
-- compute speed taking into account way type, maxspeed tags, etc.
'handle_speed',
'handle_surface',
'handle_maxspeed',
'handle_penalties',
WayHandlers.speed,
WayHandlers.surface,
WayHandlers.maxspeed,
WayHandlers.penalties,
-- compute class labels
'handle_classes',
WayHandlers.classes,
-- handle turn lanes and road classification, used for guidance
'handle_turn_lanes',
'handle_classification',
WayHandlers.turn_lanes,
WayHandlers.classification,
-- handle various other flags
'handle_roundabouts',
'handle_startpoint',
WayHandlers.roundabouts,
WayHandlers.startpoint,
-- set name, ref and pronunciation
'handle_names',
WayHandlers.names,
-- set weight properties of the way
'handle_weights'
WayHandlers.weights
}
Handlers.run(handlers,way,result,data,profile)
WayHandlers.run(profile,way,result,data,handlers)
end
function turn_function (turn)
function process_turn (profile, turn)
-- Use a sigmoid function to return a penalty that maxes out at turn_penalty
-- over the space of 0-180 degrees. Values here were chosen by fitting
-- the function to some turn penalty samples from real driving.
@@ -397,7 +383,7 @@ function turn_function (turn)
local turn_bias = profile.turn_bias
if turn.has_traffic_light then
turn.duration = profile.traffic_light_penalty
turn.duration = profile.properties.traffic_light_penalty
end
if turn.turn_type ~= turn_type.no_turn then
@@ -408,21 +394,28 @@ function turn_function (turn)
end
if turn.direction_modifier == direction_modifier.u_turn then
turn.duration = turn.duration + profile.u_turn_penalty
turn.duration = turn.duration + profile.properties.u_turn_penalty
end
end
-- for distance based routing we don't want to have penalties based on turn angle
if properties.weight_name == 'distance' then
if profile.properties.weight_name == 'distance' then
turn.weight = 0
else
turn.weight = turn.duration
end
if properties.weight_name == 'routability' then
if profile.properties.weight_name == 'routability' then
-- penalize turns from non-local access only segments onto local access only tags
if not turn.source_restricted and turn.target_restricted then
turn.weight = properties.max_turn_weight;
turn.weight = constants.max_turn_weight
end
end
end
return {
setup = setup,
process_way = process_way,
process_node = process_node,
process_turn = process_turn
}
+151 -150
View File
@@ -1,149 +1,143 @@
-- Foot profile
api_version = 1
api_version = 2
local find_access_tag = require("lib/access").find_access_tag
local Set = require('lib/set')
local Sequence = require('lib/sequence')
local Handlers = require("lib/handlers")
local next = next -- bind to local for speed
Set = require('lib/set')
Sequence = require('lib/sequence')
Handlers = require("lib/way_handlers")
find_access_tag = require("lib/access").find_access_tag
properties.max_speed_for_map_matching = 40/3.6 -- kmph -> m/s
properties.use_turn_restrictions = false
properties.continue_straight_at_waypoint = false
properties.weight_name = 'duration'
--properties.weight_name = 'routability'
-- Set to true if you need to call the node_function for every node.
-- Generally can be left as false to avoid unnecessary Lua calls
-- (which slow down pre-processing).
properties.call_tagless_node_function = false
local walking_speed = 5
local profile = {
default_mode = mode.walking,
default_speed = walking_speed,
oneway_handling = 'specific', -- respect 'oneway:foot' but not 'oneway'
traffic_light_penalty = 2,
u_turn_penalty = 2,
barrier_whitelist = Set {
'cycle_barrier',
'bollard',
'entrance',
'cattle_grid',
'border_control',
'toll_booth',
'sally_port',
'gate',
'no',
'kerb',
'block'
},
access_tag_whitelist = Set {
'yes',
'foot',
'permissive',
'designated'
},
access_tag_blacklist = Set {
'no',
'agricultural',
'forestry',
'private',
'delivery',
},
restricted_access_tag_list = Set { },
restricted_highway_whitelist = Set { },
access_tags_hierarchy = Sequence {
'foot',
'access'
},
restrictions = Sequence {
'foot'
},
-- list of suffixes to suppress in name change instructions
suffix_list = Set {
'N', 'NE', 'E', 'SE', 'S', 'SW', 'W', 'NW', 'North', 'South', 'West', 'East'
},
avoid = Set {
'impassable',
'construction',
'proposed'
},
speeds = Sequence {
highway = {
primary = walking_speed,
primary_link = walking_speed,
secondary = walking_speed,
secondary_link = walking_speed,
tertiary = walking_speed,
tertiary_link = walking_speed,
unclassified = walking_speed,
residential = walking_speed,
road = walking_speed,
living_street = walking_speed,
service = walking_speed,
track = walking_speed,
path = walking_speed,
steps = walking_speed,
pedestrian = walking_speed,
footway = walking_speed,
pier = walking_speed,
function setup()
local walking_speed = 5
return {
properties = {
weight_name = 'duration',
max_speed_for_map_matching = 40/3.6, -- kmph -> m/s
call_tagless_node_function = false,
traffic_light_penalty = 2,
u_turn_penalty = 2,
continue_straight_at_waypoint = false,
use_turn_restrictions = false,
},
railway = {
platform = walking_speed
default_mode = mode.walking,
default_speed = walking_speed,
oneway_handling = 'specific', -- respect 'oneway:foot' but not 'oneway'
barrier_whitelist = Set {
'cycle_barrier',
'bollard',
'entrance',
'cattle_grid',
'border_control',
'toll_booth',
'sally_port',
'gate',
'no',
'kerb',
'block'
},
amenity = {
parking = walking_speed,
parking_entrance= walking_speed
access_tag_whitelist = Set {
'yes',
'foot',
'permissive',
'designated'
},
man_made = {
pier = walking_speed
access_tag_blacklist = Set {
'no',
'agricultural',
'forestry',
'private',
'delivery',
},
leisure = {
track = walking_speed
restricted_access_tag_list = Set { },
restricted_highway_whitelist = Set { },
access_tags_hierarchy = Sequence {
'foot',
'access'
},
restrictions = Sequence {
'foot'
},
-- list of suffixes to suppress in name change instructions
suffix_list = Set {
'N', 'NE', 'E', 'SE', 'S', 'SW', 'W', 'NW', 'North', 'South', 'West', 'East'
},
avoid = Set {
'impassable'
},
speeds = Sequence {
highway = {
primary = walking_speed,
primary_link = walking_speed,
secondary = walking_speed,
secondary_link = walking_speed,
tertiary = walking_speed,
tertiary_link = walking_speed,
unclassified = walking_speed,
residential = walking_speed,
road = walking_speed,
living_street = walking_speed,
service = walking_speed,
track = walking_speed,
path = walking_speed,
steps = walking_speed,
pedestrian = walking_speed,
footway = walking_speed,
pier = walking_speed,
},
railway = {
platform = walking_speed
},
amenity = {
parking = walking_speed,
parking_entrance= walking_speed
},
man_made = {
pier = walking_speed
},
leisure = {
track = walking_speed
}
},
route_speeds = {
ferry = 5
},
bridge_speeds = {
},
surface_speeds = {
fine_gravel = walking_speed*0.75,
gravel = walking_speed*0.75,
pebblestone = walking_speed*0.75,
mud = walking_speed*0.5,
sand = walking_speed*0.5
},
tracktype_speeds = {
},
smoothness_speeds = {
}
},
route_speeds = {
ferry = 5
},
bridge_speeds = {
},
surface_speeds = {
fine_gravel = walking_speed*0.75,
gravel = walking_speed*0.75,
pebblestone = walking_speed*0.75,
mud = walking_speed*0.5,
sand = walking_speed*0.5
},
tracktype_speeds = {
},
smoothness_speeds = {
}
}
end
function node_function (node, result)
function process_node (profile, node, result)
-- parse access and barrier tags
local access = find_access_tag(node, profile.access_tags_hierarchy)
if access then
@@ -171,7 +165,7 @@ function node_function (node, result)
end
-- main entry point for processsing a way
function way_function(way, result)
function process_way(profile, way, result)
-- the intial filtering of ways based on presence of tags
-- affects processing times significantly, because all ways
-- have to be checked.
@@ -208,59 +202,66 @@ function way_function(way, result)
local handlers = Sequence {
-- set the default mode for this profile. if can be changed later
-- in case it turns we're e.g. on a ferry
'handle_default_mode',
WayHandlers.default_mode,
-- check various tags that could indicate that the way is not
-- routable. this includes things like status=impassable,
-- toll=yes and oneway=reversible
'handle_blocked_ways',
WayHandlers.blocked_ways,
-- determine access status by checking our hierarchy of
-- access tags, e.g: motorcar, motor_vehicle, vehicle
'handle_access',
WayHandlers.access,
-- check whether forward/backward directons are routable
'handle_oneway',
WayHandlers.oneway,
-- check whether forward/backward directons are routable
'handle_destinations',
WayHandlers.destinations,
-- check whether we're using a special transport mode
'handle_ferries',
'handle_movables',
WayHandlers.ferries,
WayHandlers.movables,
-- compute speed taking into account way type, maxspeed tags, etc.
'handle_speed',
'handle_surface',
WayHandlers.speed,
WayHandlers.surface,
-- handle turn lanes and road classification, used for guidance
'handle_classification',
WayHandlers.classification,
-- handle various other flags
'handle_roundabouts',
'handle_startpoint',
WayHandlers.roundabouts,
WayHandlers.startpoint,
-- set name, ref and pronunciation
'handle_names'
WayHandlers.names
}
Handlers.run(handlers,way,result,data,profile)
WayHandlers.run(profile,way,result,data,handlers)
end
function turn_function (turn)
function process_turn (profile, turn)
turn.duration = 0.
if turn.direction_modifier == direction_modifier.u_turn then
turn.duration = turn.duration + profile.u_turn_penalty
turn.duration = turn.duration + profile.properties.u_turn_penalty
end
if turn.has_traffic_light then
turn.duration = profile.traffic_light_penalty
turn.duration = profile.properties.traffic_light_penalty
end
if properties.weight_name == 'routability' then
if profile.properties.weight_name == 'routability' then
-- penalize turns from non-local access only segments onto local access only tags
if not turn.source_restricted and turn.target_restricted then
turn.weight = turn.weight + 3000
end
end
end
return {
setup = setup,
process_way = process_way,
process_node = process_node,
process_turn = process_turn
}
+5 -4
View File
@@ -90,7 +90,8 @@ function Debug.report_tag_fetches()
end
function Debug.load_profile(profile)
require(profile)
Debug.functions = require(profile)
Debug.profile = Debug.functions.setup()
end
function Debug.reset_tag_fetch_counts()
@@ -115,7 +116,7 @@ function Debug.register_tag_fetch(k)
end
function Debug.way_function(way,result)
function Debug.process_way(way,result)
-- setup result table
result.road_classification = {}
@@ -132,8 +133,8 @@ function Debug.way_function(way,result)
-- reset tag counts
Debug:reset_tag_fetch_counts()
-- call the global method defined in the profile file
way_function(way,result)
-- call the way processsing function
Debug.functions.process_way(Debug.profile,way,result)
end
return Debug
+1 -1
View File
@@ -1,7 +1,7 @@
-- Sequence of items
-- Ordered, but have to loop through items to check for inclusion.
-- Currently the same as a table.
-- Adds the convenience function append() to append to the sequnce.
function Sequence(source)
return source
@@ -9,25 +9,26 @@ local set_classification = require("lib/guidance").set_classification
local get_destination = require("lib/destination").get_destination
local Tags = require('lib/tags')
Handlers = {}
WayHandlers = {}
-- check that way has at least one tag that could imply routability-
-- we store the checked tags in data, to avoid fetching again later
function Handlers.handle_tag_prefetch(way,result,data,profile)
function WayHandlers.tag_prefetch(profile,way,result,data)
for key,v in pairs(profile.prefetch) do
data[key] = way:get_value_by_key( key )
end
return next(data) ~= nil
end
-- set default mode
function Handlers.handle_default_mode(way,result,data,profile)
function WayHandlers.default_mode(profile,way,result,data)
result.forward_mode = profile.default_mode
result.backward_mode = profile.default_mode
end
-- handles name, including ref and pronunciation
function Handlers.handle_names(way,result,data,profile)
function WayHandlers.names(profile,way,result,data)
-- parse the remaining tags
local name = way:get_value_by_key("name")
local pronunciation = way:get_value_by_key("name:pronunciation")
@@ -53,7 +54,7 @@ function Handlers.handle_names(way,result,data,profile)
end
-- junctions
function Handlers.handle_roundabouts(way,result,data,profile)
function WayHandlers.roundabouts(profile,way,result,data)
local junction = way:get_value_by_key("junction");
if junction == "roundabout" then
@@ -69,7 +70,7 @@ function Handlers.handle_roundabouts(way,result,data,profile)
end
-- determine if this way can be used as a start/end point for routing
function Handlers.handle_startpoint(way,result,data,profile)
function WayHandlers.startpoint(profile,way,result,data)
-- if profile specifies set of allowed start modes, then check for that
-- otherwise require default mode
if profile.allowed_start_modes then
@@ -82,7 +83,7 @@ function Handlers.handle_startpoint(way,result,data,profile)
end
-- handle turn lanes
function Handlers.handle_turn_lanes(way,result,data,profile)
function WayHandlers.turn_lanes(profile,way,result,data)
local forward, backward = get_turn_lanes(way,data)
if forward then
@@ -95,12 +96,12 @@ function Handlers.handle_turn_lanes(way,result,data,profile)
end
-- set the road classification based on guidance globals configuration
function Handlers.handle_classification(way,result,data,profile)
function WayHandlers.classification(profile,way,result,data)
set_classification(data.highway,result,way)
end
-- handle destination tags
function Handlers.handle_destinations(way,result,data,profile)
function WayHandlers.destinations(profile,way,result,data)
if data.is_forward_oneway or data.is_reverse_oneway then
local destination = get_destination(way, data.is_forward_oneway)
result.destinations = canonicalizeStringList(destination, ",")
@@ -108,7 +109,7 @@ function Handlers.handle_destinations(way,result,data,profile)
end
-- handling ferries and piers
function Handlers.handle_ferries(way,result,data,profile)
function WayHandlers.ferries(profile,way,result,data)
local route = data.route
if route then
local route_speed = profile.route_speeds[route]
@@ -126,7 +127,7 @@ function Handlers.handle_ferries(way,result,data,profile)
end
-- handling movable bridges
function Handlers.handle_movables(way,result,data,profile)
function WayHandlers.movables(profile,way,result,data)
local bridge = data.bridge
if bridge then
local bridge_speed = profile.bridge_speeds[bridge]
@@ -148,7 +149,7 @@ function Handlers.handle_movables(way,result,data,profile)
end
-- service roads
function Handlers.handle_service(way,result,data,profile)
function WayHandlers.service(profile,way,result,data)
local service = way:get_value_by_key("service")
if service then
-- Set don't allow access to certain service roads
@@ -161,7 +162,7 @@ function Handlers.handle_service(way,result,data,profile)
end
-- all lanes restricted to hov vehicles?
function Handlers.has_all_designated_hov_lanes(lanes)
function WayHandlers.has_all_designated_hov_lanes(lanes)
if not lanes then
return false
end
@@ -176,7 +177,7 @@ function Handlers.has_all_designated_hov_lanes(lanes)
end
-- handle high occupancy vehicle tags
function Handlers.handle_hov(way,result,data,profile)
function WayHandlers.hov(profile,way,result,data)
-- respect user-preference for HOV
if not profile.avoid.hov_lanes then
return
@@ -189,11 +190,11 @@ function Handlers.handle_hov(way,result,data,profile)
end
data.hov_lanes_forward, data.hov_lanes_backward = Tags.get_forward_backward_by_key(way,data,'hov:lanes')
local all_hov_forward = Handlers.has_all_designated_hov_lanes(data.hov_lanes_forward)
local all_hov_backward = Handlers.has_all_designated_hov_lanes(data.hov_lanes_backward)
local all_hov_forward = WayHandlers.has_all_designated_hov_lanes(data.hov_lanes_forward)
local all_hov_backward = WayHandlers.has_all_designated_hov_lanes(data.hov_lanes_backward)
-- in this case we will use turn penalties instead of filtering out
if properties.weight_name == 'routability' then
if profile.properties.weight_name == 'routability' then
if (all_hov_forward) then
result.forward_restricted = true
end
@@ -213,7 +214,7 @@ function Handlers.handle_hov(way,result,data,profile)
end
-- check accessibility by traversing our access tag hierarchy
function Handlers.handle_access(way,result,data,profile)
function WayHandlers.access(profile,way,result,data)
data.forward_access, data.backward_access =
Tags.get_forward_backward_by_set(way,data,profile.access_tags_hierarchy)
@@ -242,7 +243,7 @@ function Handlers.handle_access(way,result,data,profile)
end
-- handle speed (excluding maxspeed)
function Handlers.handle_speed(way,result,data,profile)
function WayHandlers.speed(profile,way,result,data)
if result.forward_speed ~= -1 then
return -- abort if already set, eg. by a route
end
@@ -278,7 +279,7 @@ function Handlers.handle_speed(way,result,data,profile)
end
-- add class information
function Handlers.handle_classes(way,result,data,profile)
function WayHandlers.classes(profile,way,result,data)
local forward_toll, backward_toll = Tags.get_forward_backward_by_key(way, data, "toll")
local forward_route, backward_route = Tags.get_forward_backward_by_key(way, data, "route")
@@ -310,7 +311,7 @@ function Handlers.handle_classes(way,result,data,profile)
end
-- reduce speed on bad surfaces
function Handlers.handle_surface(way,result,data,profile)
function WayHandlers.surface(profile,way,result,data)
local surface = way:get_value_by_key("surface")
local tracktype = way:get_value_by_key("tracktype")
local smoothness = way:get_value_by_key("smoothness")
@@ -330,7 +331,7 @@ function Handlers.handle_surface(way,result,data,profile)
end
-- scale speeds to get better average driving times
function Handlers.handle_penalties(way,result,data,profile)
function WayHandlers.penalties(profile,way,result,data)
-- heavily penalize a way tagged with all HOV lanes
-- in order to only route over them if there is no other option
local service_penalty = 1.0
@@ -375,7 +376,7 @@ function Handlers.handle_penalties(way,result,data,profile)
local forward_penalty = math.min(service_penalty, width_penalty, alternating_penalty, sideroad_penalty)
local backward_penalty = math.min(service_penalty, width_penalty, alternating_penalty, sideroad_penalty)
if properties.weight_name == 'routability' then
if profile.properties.weight_name == 'routability' then
if result.forward_speed > 0 then
result.forward_rate = (result.forward_speed * forward_penalty) / 3.6
end
@@ -389,11 +390,11 @@ function Handlers.handle_penalties(way,result,data,profile)
end
-- maxspeed and advisory maxspeed
function Handlers.handle_maxspeed(way,result,data,profile)
function WayHandlers.maxspeed(profile,way,result,data)
local keys = Sequence { 'maxspeed:advisory', 'maxspeed' }
local forward, backward = Tags.get_forward_backward_by_set(way,data,keys)
forward = Handlers.parse_maxspeed(forward,profile)
backward = Handlers.parse_maxspeed(backward,profile)
forward = WayHandlers.parse_maxspeed(forward,profile)
backward = WayHandlers.parse_maxspeed(backward,profile)
if forward and forward > 0 then
result.forward_speed = forward * profile.speed_reduction
@@ -404,7 +405,7 @@ function Handlers.handle_maxspeed(way,result,data,profile)
end
end
function Handlers.parse_maxspeed(source,profile)
function WayHandlers.parse_maxspeed(source,profile)
if not source then
return 0
end
@@ -429,7 +430,7 @@ function Handlers.parse_maxspeed(source,profile)
end
-- handle oneways tags
function Handlers.handle_oneway(way,result,data,profile)
function WayHandlers.oneway(profile,way,result,data)
if not profile.oneway_handling then
return
end
@@ -476,8 +477,8 @@ function Handlers.handle_oneway(way,result,data,profile)
end
end
function Handlers.handle_weights(way,result,data,profile)
if properties.weight_name == 'distance' then
function WayHandlers.weights(profile,way,result,data)
if profile.properties.weight_name == 'distance' then
result.weight = -1
-- set weight rates to 1 for the distance weight, edge weights are distance / rate
if (result.forward_mode ~= mode.inaccessible and result.forward_speed > 0) then
@@ -490,7 +491,7 @@ function Handlers.handle_weights(way,result,data,profile)
end
-- handle various that can block access
function Handlers.handle_blocked_ways(way,result,data,profile)
function WayHandlers.blocked_ways(profile,way,result,data)
-- areas
if profile.avoid.area and way:get_value_by_key("area") == "yes" then
@@ -554,27 +555,27 @@ end
-- Call a sequence of handlers, aborting in case a handler returns false. Example:
--
-- handlers = Sequence {
-- 'handle_tag_prefetch',
-- 'handle_default_mode',
-- 'handle_blocked_ways',
-- 'handle_access',
-- 'handle_speed',
-- 'handle_names'
-- WayHandlers.tag_prefetch,
-- WayHandlers.default_mode,
-- WayHandlers.blocked_ways,
-- WayHandlers.access,
-- WayHandlers.speed,
-- WayHandlers.names
-- }
--
-- Handlers.run(handlers,way,result,data,profile)
-- WayHandlers.run(handlers,way,result,data,profile)
--
-- Each method in the list will be called on the Handlers object.
-- All handlers must accept the parameteres (way,result,data,profile) and return false
-- Each method in the list will be called on the WayHandlers object.
-- All handlers must accept the parameteres (profile,way,result,data) and return false
-- if the handler chain should be aborted.
-- To ensure the correct order of method calls, use a Sequence of handler names.
function Handlers.run(handlers,way,result,data,profile)
function WayHandlers.run(profile,way,result,data,handlers)
for i,handler in ipairs(handlers) do
if Handlers[handler](way,result,data,profile) == false then
if handler(profile,way,result,data) == false then
return false
end
end
end
return Handlers
return WayHandlers
+30 -29
View File
@@ -1,19 +1,30 @@
api_version = 1
-- Rasterbot profile
properties.force_split_edges = true
api_version = 2
-- Set to true if you need to call the node_function for every node.
-- Generally can be left as false to avoid unnecessary Lua calls
-- (which slow down pre-processing).
properties.call_tagless_node_function = false
function setup()
local raster_path = os.getenv('OSRM_RASTER_SOURCE') or "rastersource.asc"
-- Minimalist node_ and way_functions in order to test source_ and segment_functions
function node_function (node, result)
return {
properties = {
force_split_edges = true,
process_call_tagless_node = false,
},
raster_source = raster:load(
raster_path,
0, -- lon_min
0.1, -- lon_max
0, -- lat_min
0.1, -- lat_max
5, -- nrows
4 -- ncols
)
}
end
function way_function (way, result)
-- Minimalist process_ways in order to test source_ and process_segments
function process_way (profile, way, result)
local highway = way:get_value_by_key("highway")
local name = way:get_value_by_key("name")
@@ -28,25 +39,9 @@ function way_function (way, result)
result.backward_speed = 15
end
function source_function ()
local path = os.getenv('OSRM_RASTER_SOURCE')
if not path then
path = "rastersource.asc"
end
raster_source = sources:load(
path,
0, -- lon_min
0.1, -- lon_max
0, -- lat_min
0.1, -- lat_max
5, -- nrows
4 -- ncols
)
end
function segment_function (segment)
local sourceData = sources:query(raster_source, segment.source.lon, segment.source.lat)
local targetData = sources:query(raster_source, segment.target.lon, segment.target.lat)
function process_segment (profile, segment)
local sourceData = raster:query(profile.raster_source, segment.source.lon, segment.source.lat)
local targetData = raster:query(profile.raster_source, segment.target.lon, segment.target.lat)
io.write("evaluating segment: " .. sourceData.datum .. " " .. targetData.datum .. "\n")
local invalid = sourceData.invalid_data()
local scaled_weight = segment.weight
@@ -66,3 +61,9 @@ function segment_function (segment)
segment.weight = scaled_weight
segment.duration = scaled_duration
end
return {
setup = setup,
process_way = process_way,
process_segment = process_segment
}
+7 -45
View File
@@ -1,50 +1,10 @@
api_version = 1
-- Rasterbot profile
-- Rasterbot with interpolation profile
-- Set to true if you need to call the node_function for every node.
-- Generally can be left as false to avoid unnecessary Lua calls
-- (which slow down pre-processing).
properties.call_tagless_node_function = false
functions = require('rasterbot')
-- Minimalist node_ and way_functions in order to test source_ and segment_functions
function node_function (node, result)
end
function way_function (way, result)
local highway = way:get_value_by_key("highway")
local name = way:get_value_by_key("name")
if name then
result.name = name
end
result.forward_mode = mode.cycling
result.backward_mode = mode.cycling
result.forward_speed = 15
result.backward_speed = 15
end
function source_function ()
local path = os.getenv('OSRM_RASTER_SOURCE')
if not path then
path = "rastersource.asc"
end
raster_source = sources:load(
path,
0, -- lon_min
0.1, -- lon_max
0, -- lat_min
0.1, -- lat_max
5, -- nrows
4 -- ncols
)
end
function segment_function (segment)
local sourceData = sources:interpolate(raster_source, segment.source.lon, segment.source.lat)
local targetData = sources:interpolate(raster_source, segment.target.lon, segment.target.lat)
functions.process_segment = function(profile, segment)
local sourceData = raster:interpolate(profile.raster_source, segment.source.lon, segment.source.lat)
local targetData = raster:interpolate(profile.raster_source, segment.target.lon, segment.target.lat)
io.write("evaluating segment: " .. sourceData.datum .. " " .. targetData.datum .. "\n")
local invalid = sourceData.invalid_data()
local scaled_weight = segment.weight
@@ -64,3 +24,5 @@ function segment_function (segment)
segment.weight = scaled_weight
segment.duration = scaled_duration
end
return functions
+34 -41
View File
@@ -1,49 +1,35 @@
api_version = 1
-- Testbot profile
-- Moves at fixed, well-known speeds, practical for testing speed and travel times:
-- Primary road: 36km/h = 36000m/3600s = 100m/10s
-- Secondary road: 18km/h = 18000m/3600s = 100m/20s
-- Tertiary road: 12km/h = 12000m/3600s = 100m/30s
speed_profile = {
["primary"] = 36,
["secondary"] = 18,
["tertiary"] = 12,
["steps"] = 6,
["default"] = 24
}
api_version = 2
-- these settings are read directly by osrm
function setup()
return {
properties = {
continue_straight_at_waypoint = true,
max_speed_for_map_matching = 30/3.6, --km -> m/s
weight_name = 'duration',
process_call_tagless_node = false,
uturn_penalty = 20,
traffic_light_penalty = 7, -- seconds
use_turn_restrictions = true
},
properties.continue_straight_at_waypoint = true
properties.use_turn_restrictions = true
properties.max_speed_for_map_matching = 30/3.6 --km -> m/s
properties.weight_name = 'duration'
-- Set to true if you need to call the node_function for every node.
-- Generally can be left as false to avoid unnecessary Lua calls
-- (which slow down pre-processing).
properties.call_tagless_node_function = false
local uturn_penalty = 20
local traffic_light_penalty = 7 -- seconds
function limit_speed(speed, limits)
-- don't use ipairs(), since it stops at the first nil value
for i=1, #limits do
limit = limits[i]
if limit ~= nil and limit > 0 then
if limit < speed then
return limit -- stop at first speedlimit that's smaller than speed
end
end
end
return speed
default_speed = 24,
speeds = {
primary = 36,
secondary = 18,
tertiary = 12,
steps = 6,
}
}
end
function node_function (node, result)
function process_node (profile, node, result)
local traffic_signal = node:get_value_by_key("highway")
if traffic_signal and traffic_signal == "traffic_signals" then
@@ -52,7 +38,7 @@ function node_function (node, result)
end
end
function way_function (way, result)
function process_way (profile, way, result)
local highway = way:get_value_by_key("highway")
local name = way:get_value_by_key("name")
local oneway = way:get_value_by_key("oneway")
@@ -75,7 +61,7 @@ function way_function (way, result)
result.forward_mode = mode.route
result.backward_mode = mode.route
else
local speed_forw = speed_profile[highway] or speed_profile['default']
local speed_forw = profile.speeds[highway] or profile.default_speed
local speed_back = speed_forw
if highway == "river" then
@@ -122,12 +108,19 @@ function way_function (way, result)
end
end
function turn_function (turn)
function process_turn (profile, turn)
if turn.direction_modifier == direction_modifier.uturn then
turn.duration = uturn_penalty
turn.weight = uturn_penalty
turn.duration = profile.properties.uturn_penalty
turn.weight = profile.properties.uturn_penalty
end
if turn.has_traffic_light then
turn.duration = turn.duration + traffic_light_penalty
turn.duration = turn.duration + profile.properties.traffic_light_penalty
end
end
return {
setup = setup,
process_way = process_way,
process_node = process_node,
process_turn = process_turn
}
+5 -5
View File
@@ -1,10 +1,10 @@
api_version = 1
-- Testbot, with turn penalty
-- Used for testing turn penalties
require 'testbot'
functions = require 'testbot'
function turn_function (turn)
turn.duration = 20 * math.abs(turn.angle) / 180
functions.process_turn = function(profile, turn)
turn.duration = 20 * math.abs(turn.angle) / 180
end
return functions