osrm startup helpers added

This commit is contained in:
muerwre 2018-08-27 15:51:26 +07:00
parent d9f83425f6
commit eb091cc1a4
14 changed files with 1928 additions and 0 deletions

422
osrm/rules.lua Normal file
View file

@ -0,0 +1,422 @@
-- Car profile
api_version = 1
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
penalty_table = {
["service"] = 0.5,
}
-- set profile properties
properties.max_speed_for_map_matching = 15 -- 180kmph -> m/s
properties.use_turn_restrictions = false
properties.continue_straight_at_waypoint = false
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'
local profile = {
default_mode = mode.driving,
default_speed = 10,
oneway_handling = true,
side_road_multiplier = 0.8,
turn_penalty = 12,
speed_reduction = 0.8,
traffic_light_penalty = 2,
u_turn_penalty = 20,
restricted_penalty = 3000,
-- Note^: abstract value but in seconds correlates approximately to 50 min
-- meaning that a route through a local access way is > 50 min faster than around
-- 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,
-- a list of suffixes to suppress in name change instructions
suffix_list = {
'N', 'NE', 'E', 'SE', 'S', 'SW', 'W', 'NW', 'North', 'South', 'West', 'East'
},
barrier_whitelist = Set {
'cattle_grid',
'border_control',
'checkpoint',
'toll_booth',
'sally_port',
'gate',
'lift_gate',
'no',
'entrance'
},
access_tag_whitelist = Set {
'yes',
'residential',
'primary',
'secondary',
'motorcar',
'motor_vehicle',
'vehicle',
'track',
'permissive',
'designated',
'hov'
},
access_tag_blacklist = Set {
-- 'no',
-- 'agricultural',
-- 'forestry',
-- 'emergency',
-- 'psv'
},
restricted_access_tag_list = Set {
-- 'private',
-- 'delivery',
-- 'destination'
},
access_tags_hierarchy = Sequence {
'motorcar',
'motor_vehicle',
'vehicle',
'residential',
'track',
'foot',
'bicycle',
'access'
},
service_tag_forbidden = Set {
'emergency_access'
},
restrictions = Sequence {
-- 'motorcar',
-- 'motor_vehicle',
-- 'vehicle'
},
avoid = Set {
-- 'area',
-- 'toll', -- uncomment this to avoid tolls
-- 'reversible',
'impassable',
-- 'hov_lanes',
-- 'steps'
},
speeds = Sequence {
highway = {
motorway = 80,
cycleway = 110,
motorway_link = 80,
trunk = 80,
trunk_link = 100,
primary = 100,
primary_link = 100,
secondary = 90,
secondary_link = 90,
tertiary = 80,
tertiary_link = 80,
unclassified = 80,
residential = 80,
living_street = 75,
service = 75,
road = 90,
track = 95,
path = 70,
steps = 15,
pedestrian = 70,
footway = 80,
footpath = 100,
foot_path = 100,
pier = 95,
unpaved = 95
}
},
service_penalties = {
-- alley = 0.5,
-- parking = 0.5,
-- parking_aisle = 0.5,
-- driveway = 0.5,
-- ["drive-through"] = 0.5,
-- ["drive-thru"] = 0.5
},
route_speeds = {
ferry = 5,
shuttle_train = 10
},
bridge_speeds = {
movable = nil
},
-- 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 = nil,
compacted = nil,
fine_gravel = nil,
paving_stones = nil,
metal = nil,
bricks = nil,
grass = 50,
wood = nil,
sett = nil,
grass_paver = 80,
gravel = 80,
unpaved = nil,
ground = 80,
dirt = 60,
pebblestone = nil,
tartan = 50,
cobblestone = 60,
clay = 60,
earth = 60,
stone = 60,
rocky = 50,
sand = 40,
mud = 40
},
-- 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)
-- parse access and barrier tags
local access = find_access_tag(node, profile.access_tags_hierarchy)
if access then
if profile.access_tag_blacklist[access] then
result.barrier = true
end
else
local barrier = node:get_value_by_key("barrier")
if barrier then
-- make an exception for rising bollard barriers
local bollard = node:get_value_by_key("bollard")
local rising_bollard = bollard and "rising" == bollard
if not profile.barrier_whitelist[barrier] and not rising_bollard then
result.barrier = true
end
end
end
-- check if node is a traffic light
local tag = node:get_value_by_key("highway")
if "traffic_signals" == tag then
result.traffic_lights = true
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'),
bridge = way:get_value_by_key('bridge'),
route = way:get_value_by_key('route')
}
-- perform an quick initial check and abort if the way is
-- obviously not routable.
-- highway or route tags must be in data table, bridge is optional
if (not data.highway or data.highway == '') and
(not data.route or data.route == '')
then
return
end
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',
-- determine access status by checking our hierarchy of
-- access tags, e.g: motorcar, motor_vehicle, vehicle
'handle_access',
-- check whether forward/backward directions are routable
'handle_oneway',
-- check whether forward/backward directions are routable
'handle_destinations',
-- check whether we're using a special transport mode
'handle_ferries',
'handle_movables',
-- handle service road restrictions
'handle_service',
-- handle hov
'handle_hov',
-- compute speed taking into account way type, maxspeed tags, etc.
'handle_speed',
'handle_surface',
'handle_maxspeed',
'handle_penalties',
-- handle turn lanes and road classification, used for guidance
'handle_turn_lanes',
'handle_classification',
-- handle various other flags
-- 'handle_roundabouts',
'handle_startpoint',
-- set name, ref and pronunciation
'handle_names',
-- set weight properties of the way
'handle_weights'
}
Handlers.run(handlers,way,result,data,profile)
end
function turn_function (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.
local turn_penalty = profile.turn_penalty
local turn_bias = profile.turn_bias
if turn.turn_type ~= turn_type.no_turn then
if turn.angle >= 0 then
turn.duration = turn_penalty / (1 + math.exp( -((13 / turn_bias) * turn.angle/180 - 6.5*turn_bias)))
else
turn.duration = turn_penalty / (1 + math.exp( -((13 * turn_bias) * -turn.angle/180 - 6.5/turn_bias)))
end
if turn.direction_modifier == direction_modifier.u_turn then
turn.duration = turn.duration + profile.u_turn_penalty
end
if turn.has_traffic_light then
turn.duration = turn.duration + profile.traffic_light_penalty
end
-- for distance based routing we don't want to have penalties based on turn angle
if properties.weight_name == 'distance' then
turn.weight = 0
else
turn.weight = turn.duration
end
if 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 + profile.restricted_penalty
end
end
end
end