2017-01-23 15:23:33 -05:00
|
|
|
-- Car profile
|
|
|
|
|
2017-11-03 13:30:46 -04:00
|
|
|
api_version = 4
|
2017-05-18 08:27:28 -04:00
|
|
|
|
|
|
|
Set = require('lib/set')
|
|
|
|
Sequence = require('lib/sequence')
|
|
|
|
Handlers = require("lib/way_handlers")
|
2017-09-05 09:41:55 -04:00
|
|
|
Relations = require("lib/relations")
|
2022-08-30 05:36:49 -04:00
|
|
|
TrafficSignal = require("lib/traffic_signal")
|
2017-05-18 08:27:28 -04:00
|
|
|
find_access_tag = require("lib/access").find_access_tag
|
|
|
|
limit = require("lib/maxspeed").limit
|
2017-09-13 08:30:44 -04:00
|
|
|
Utils = require("lib/utils")
|
2018-02-12 03:02:20 -05:00
|
|
|
Measure = require("lib/measure")
|
2017-05-18 08:27:28 -04:00
|
|
|
|
|
|
|
function setup()
|
|
|
|
return {
|
|
|
|
properties = {
|
|
|
|
max_speed_for_map_matching = 180/3.6, -- 180kmph -> m/s
|
|
|
|
-- 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,
|
2017-08-21 07:41:27 -04:00
|
|
|
left_hand_driving = false,
|
2017-05-18 08:27:28 -04:00
|
|
|
traffic_light_penalty = 2,
|
|
|
|
},
|
2017-07-19 09:32:42 -04:00
|
|
|
|
2017-05-18 08:27:28 -04:00
|
|
|
default_mode = mode.driving,
|
|
|
|
default_speed = 10,
|
|
|
|
oneway_handling = true,
|
|
|
|
side_road_multiplier = 0.8,
|
|
|
|
turn_penalty = 7.5,
|
|
|
|
speed_reduction = 0.8,
|
2017-08-15 10:53:27 -04:00
|
|
|
turn_bias = 1.075,
|
2017-10-24 20:21:08 -04:00
|
|
|
cardinal_directions = false,
|
2017-05-18 08:27:28 -04:00
|
|
|
|
2017-08-14 10:29:38 -04:00
|
|
|
-- Size of the vehicle, to be limited by physical restriction of the way
|
2019-03-04 05:27:16 -05:00
|
|
|
vehicle_height = 2.0, -- in meters, 2.0m is the height slightly above biggest SUVs
|
2018-01-09 04:27:19 -05:00
|
|
|
vehicle_width = 1.9, -- in meters, ways with narrow tag are considered narrower than 2.2m
|
2017-08-14 10:29:38 -04:00
|
|
|
|
2018-06-06 07:50:48 -04:00
|
|
|
-- Size of the vehicle, to be limited mostly by legal restriction of the way
|
2019-03-04 05:27:16 -05:00
|
|
|
vehicle_length = 4.8, -- in meters, 4.8m is the length of large or family car
|
2019-02-20 13:19:18 -05:00
|
|
|
vehicle_weight = 2000, -- in kilograms
|
2018-06-06 07:50:48 -04:00
|
|
|
|
2017-08-17 09:31:13 -04:00
|
|
|
-- a list of suffixes to suppress in name change instructions. The suffixes also include common substrings of each other
|
2017-05-18 08:27:28 -04:00
|
|
|
suffix_list = {
|
2017-08-17 09:31:13 -04:00
|
|
|
'N', 'NE', 'E', 'SE', 'S', 'SW', 'W', 'NW', 'North', 'South', 'West', 'East', 'Nor', 'Sou', 'We', 'Ea'
|
2017-05-18 08:27:28 -04:00
|
|
|
},
|
|
|
|
|
|
|
|
barrier_whitelist = Set {
|
|
|
|
'cattle_grid',
|
|
|
|
'border_control',
|
|
|
|
'toll_booth',
|
|
|
|
'sally_port',
|
|
|
|
'gate',
|
|
|
|
'lift_gate',
|
|
|
|
'no',
|
2018-02-12 03:02:20 -05:00
|
|
|
'entrance',
|
2019-02-04 19:14:43 -05:00
|
|
|
'height_restrictor',
|
|
|
|
'arch'
|
2017-05-18 08:27:28 -04:00
|
|
|
},
|
|
|
|
|
|
|
|
access_tag_whitelist = Set {
|
|
|
|
'yes',
|
|
|
|
'motorcar',
|
|
|
|
'motor_vehicle',
|
|
|
|
'vehicle',
|
|
|
|
'permissive',
|
|
|
|
'designated',
|
|
|
|
'hov'
|
|
|
|
},
|
|
|
|
|
|
|
|
access_tag_blacklist = Set {
|
|
|
|
'no',
|
|
|
|
'agricultural',
|
|
|
|
'forestry',
|
|
|
|
'emergency',
|
|
|
|
'psv',
|
|
|
|
'customers',
|
|
|
|
'private',
|
|
|
|
'delivery',
|
|
|
|
'destination'
|
|
|
|
},
|
|
|
|
|
2018-01-09 04:27:19 -05:00
|
|
|
-- tags disallow access to in combination with highway=service
|
|
|
|
service_access_tag_blacklist = Set {
|
|
|
|
'private'
|
|
|
|
},
|
|
|
|
|
2017-05-18 08:27:28 -04:00
|
|
|
restricted_access_tag_list = Set {
|
|
|
|
'private',
|
|
|
|
'delivery',
|
|
|
|
'destination',
|
|
|
|
'customers',
|
|
|
|
},
|
|
|
|
|
|
|
|
access_tags_hierarchy = Sequence {
|
|
|
|
'motorcar',
|
|
|
|
'motor_vehicle',
|
|
|
|
'vehicle',
|
|
|
|
'access'
|
|
|
|
},
|
|
|
|
|
|
|
|
service_tag_forbidden = Set {
|
|
|
|
'emergency_access'
|
|
|
|
},
|
|
|
|
|
|
|
|
restrictions = Sequence {
|
|
|
|
'motorcar',
|
|
|
|
'motor_vehicle',
|
|
|
|
'vehicle'
|
|
|
|
},
|
|
|
|
|
2017-08-14 18:18:57 -04:00
|
|
|
classes = Sequence {
|
2018-01-19 09:47:27 -05:00
|
|
|
'toll', 'motorway', 'ferry', 'restricted', 'tunnel'
|
2017-08-14 18:18:57 -04:00
|
|
|
},
|
|
|
|
|
2017-08-16 16:21:19 -04:00
|
|
|
-- classes to support for exclude flags
|
|
|
|
excludable = Sequence {
|
2017-08-14 18:18:57 -04:00
|
|
|
Set {'toll'},
|
|
|
|
Set {'motorway'},
|
|
|
|
Set {'ferry'}
|
2017-07-18 17:05:37 -04:00
|
|
|
},
|
|
|
|
|
2017-05-18 08:27:28 -04:00
|
|
|
avoid = Set {
|
|
|
|
'area',
|
|
|
|
-- 'toll', -- uncomment this to avoid tolls
|
|
|
|
'reversible',
|
|
|
|
'impassable',
|
|
|
|
'hov_lanes',
|
|
|
|
'steps',
|
|
|
|
'construction',
|
|
|
|
'proposed'
|
|
|
|
},
|
|
|
|
|
|
|
|
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_penalties = {
|
|
|
|
alley = 0.5,
|
|
|
|
parking = 0.5,
|
|
|
|
parking_aisle = 0.5,
|
|
|
|
driveway = 0.5,
|
|
|
|
["drive-through"] = 0.5,
|
|
|
|
["drive-thru"] = 0.5
|
|
|
|
},
|
|
|
|
|
2017-07-19 09:32:42 -04:00
|
|
|
restricted_highway_whitelist = Set {
|
|
|
|
'motorway',
|
|
|
|
'motorway_link',
|
|
|
|
'trunk',
|
|
|
|
'trunk_link',
|
|
|
|
'primary',
|
|
|
|
'primary_link',
|
|
|
|
'secondary',
|
|
|
|
'secondary_link',
|
|
|
|
'tertiary',
|
|
|
|
'tertiary_link',
|
|
|
|
'residential',
|
|
|
|
'living_street',
|
2018-01-09 04:27:19 -05:00
|
|
|
'unclassified',
|
|
|
|
'service'
|
2017-05-18 08:27:28 -04:00
|
|
|
},
|
|
|
|
|
2017-07-19 09:33:19 -04:00
|
|
|
construction_whitelist = Set {
|
|
|
|
'no',
|
|
|
|
'widening',
|
|
|
|
'minor',
|
|
|
|
},
|
|
|
|
|
2017-05-18 08:27:28 -04:00
|
|
|
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 = {
|
2017-10-08 08:28:47 -04:00
|
|
|
["at:rural"] = 100,
|
|
|
|
["at:trunk"] = 100,
|
2017-09-15 14:09:23 -04:00
|
|
|
["be:motorway"] = 120,
|
2020-12-02 07:32:12 -05:00
|
|
|
["be-bru:rural"] = 70,
|
|
|
|
["be-bru:urban"] = 30,
|
2018-12-14 23:42:44 -05:00
|
|
|
["be-vlg:rural"] = 70,
|
2023-09-13 16:01:36 -04:00
|
|
|
["bg:motorway"] = 140,
|
2018-01-02 08:49:36 -05:00
|
|
|
["by:urban"] = 60,
|
|
|
|
["by:motorway"] = 110,
|
2022-11-06 15:27:03 -05:00
|
|
|
["ca-on:rural"] = 80,
|
2017-05-18 08:27:28 -04:00
|
|
|
["ch:rural"] = 80,
|
|
|
|
["ch:trunk"] = 100,
|
|
|
|
["ch:motorway"] = 120,
|
|
|
|
["cz:trunk"] = 0,
|
|
|
|
["cz:motorway"] = 0,
|
2017-10-08 08:28:47 -04:00
|
|
|
["de:living_street"] = 7,
|
|
|
|
["de:rural"] = 100,
|
2017-05-18 08:27:28 -04:00
|
|
|
["de:motorway"] = 0,
|
2017-10-08 08:28:47 -04:00
|
|
|
["dk:rural"] = 80,
|
2022-11-06 15:27:03 -05:00
|
|
|
["es:trunk"] = 90,
|
2018-07-06 08:35:01 -04:00
|
|
|
["fr:rural"] = 80,
|
2017-05-18 08:27:28 -04:00
|
|
|
["gb:nsl_single"] = (60*1609)/1000,
|
|
|
|
["gb:nsl_dual"] = (70*1609)/1000,
|
|
|
|
["gb:motorway"] = (70*1609)/1000,
|
2017-10-08 08:28:47 -04:00
|
|
|
["nl:rural"] = 80,
|
|
|
|
["nl:trunk"] = 100,
|
2017-10-08 09:19:24 -04:00
|
|
|
['no:rural'] = 80,
|
|
|
|
['no:motorway'] = 110,
|
2024-03-16 07:35:25 -04:00
|
|
|
['ph:urban'] = 40,
|
|
|
|
['ph:rural'] = 80,
|
|
|
|
['ph:motorway'] = 100,
|
2017-10-08 09:19:24 -04:00
|
|
|
['pl:rural'] = 100,
|
|
|
|
['pl:trunk'] = 120,
|
|
|
|
['pl:motorway'] = 140,
|
2017-10-08 08:28:47 -04:00
|
|
|
["ro:trunk"] = 100,
|
|
|
|
["ru:living_street"] = 20,
|
|
|
|
["ru:urban"] = 60,
|
|
|
|
["ru:motorway"] = 110,
|
2017-05-18 08:27:28 -04:00
|
|
|
["uk:nsl_single"] = (60*1609)/1000,
|
|
|
|
["uk:nsl_dual"] = (70*1609)/1000,
|
|
|
|
["uk:motorway"] = (70*1609)/1000,
|
2017-10-08 09:19:24 -04:00
|
|
|
['za:urban'] = 60,
|
|
|
|
['za:rural'] = 100,
|
2017-05-18 08:27:28 -04:00
|
|
|
["none"] = 140
|
2017-09-27 12:05:05 -04:00
|
|
|
},
|
|
|
|
|
|
|
|
relation_types = Sequence {
|
|
|
|
"route"
|
2018-01-24 15:39:55 -05:00
|
|
|
},
|
|
|
|
|
|
|
|
-- classify highway tags when necessary for turn weights
|
|
|
|
highway_turn_classification = {
|
|
|
|
},
|
|
|
|
|
|
|
|
-- classify access tags when necessary for turn weights
|
|
|
|
access_turn_classification = {
|
2017-01-23 15:23:33 -05:00
|
|
|
}
|
|
|
|
}
|
2016-04-22 05:31:46 -04:00
|
|
|
end
|
|
|
|
|
2017-09-05 09:41:55 -04:00
|
|
|
function process_node(profile, node, result, relations)
|
2014-03-27 16:19:26 -04:00
|
|
|
-- parse access and barrier tags
|
2017-01-23 15:23:33 -05:00
|
|
|
local access = find_access_tag(node, profile.access_tags_hierarchy)
|
2016-11-13 17:05:01 -05:00
|
|
|
if access then
|
2017-03-03 07:38:11 -05:00
|
|
|
if profile.access_tag_blacklist[access] and not profile.restricted_access_tag_list[access] then
|
2014-08-27 10:44:40 -04:00
|
|
|
result.barrier = true
|
2014-03-27 16:19:26 -04:00
|
|
|
end
|
2014-08-27 10:44:40 -04:00
|
|
|
else
|
|
|
|
local barrier = node:get_value_by_key("barrier")
|
2016-11-13 17:05:01 -05:00
|
|
|
if barrier then
|
2018-02-12 03:02:20 -05:00
|
|
|
-- check height restriction barriers
|
|
|
|
local restricted_by_height = false
|
|
|
|
if barrier == 'height_restrictor' then
|
|
|
|
local maxheight = Measure.get_max_height(node:get_value_by_key("maxheight"), node)
|
|
|
|
restricted_by_height = maxheight and maxheight < profile.vehicle_height
|
|
|
|
end
|
|
|
|
|
2015-08-25 08:46:05 -04:00
|
|
|
-- make an exception for rising bollard barriers
|
|
|
|
local bollard = node:get_value_by_key("bollard")
|
|
|
|
local rising_bollard = bollard and "rising" == bollard
|
|
|
|
|
2021-03-30 19:28:01 -04:00
|
|
|
-- make an exception for lowered/flat barrier=kerb
|
|
|
|
-- and incorrect tagging of highway crossing kerb as highway barrier
|
|
|
|
local kerb = node:get_value_by_key("kerb")
|
|
|
|
local highway = node:get_value_by_key("highway")
|
|
|
|
local flat_kerb = kerb and ("lowered" == kerb or "flush" == kerb)
|
|
|
|
local highway_crossing_kerb = barrier == "kerb" and highway and highway == "crossing"
|
|
|
|
|
|
|
|
if not profile.barrier_whitelist[barrier]
|
|
|
|
and not rising_bollard
|
|
|
|
and not flat_kerb
|
|
|
|
and not highway_crossing_kerb
|
|
|
|
or restricted_by_height then
|
2014-08-27 10:44:40 -04:00
|
|
|
result.barrier = true
|
|
|
|
end
|
2014-03-27 16:19:26 -04:00
|
|
|
end
|
|
|
|
end
|
2012-09-19 12:35:45 -04:00
|
|
|
|
2014-08-27 10:44:40 -04:00
|
|
|
-- check if node is a traffic light
|
2022-08-30 05:36:49 -04:00
|
|
|
result.traffic_lights = TrafficSignal.get_value(node)
|
2014-08-27 10:44:40 -04:00
|
|
|
end
|
2014-07-24 12:00:37 -04:00
|
|
|
|
2017-09-22 08:03:12 -04:00
|
|
|
function process_way(profile, way, result, relations)
|
2017-01-23 15:23:33 -05:00
|
|
|
-- 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.
|
2016-11-17 07:56:17 -05:00
|
|
|
|
2017-01-23 15:23:33 -05:00
|
|
|
-- in general we should try to abort as soon as
|
2016-11-17 07:56:17 -05:00
|
|
|
-- possible if the way is not routable, to avoid doing
|
|
|
|
-- unnecessary work. this implies we should check things that
|
2017-02-01 14:35:29 -05:00
|
|
|
-- commonly forbids access early, and handle edge cases later.
|
2017-01-23 15:23:33 -05:00
|
|
|
|
|
|
|
-- data table for storing intermediate values during processing
|
|
|
|
local data = {
|
|
|
|
-- prefetch tags
|
|
|
|
highway = way:get_value_by_key('highway'),
|
2017-02-21 16:13:25 -05:00
|
|
|
bridge = way:get_value_by_key('bridge'),
|
2017-01-23 15:23:33 -05:00
|
|
|
route = way:get_value_by_key('route')
|
|
|
|
}
|
|
|
|
|
|
|
|
-- perform an quick initial check and abort if the way is
|
2017-07-03 06:18:35 -04:00
|
|
|
-- obviously not routable.
|
2017-02-21 16:13:25 -05:00
|
|
|
-- 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
|
2017-01-23 15:23:33 -05:00
|
|
|
return
|
|
|
|
end
|
2016-11-17 07:56:17 -05:00
|
|
|
|
2017-01-23 15:23:33 -05:00
|
|
|
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
|
2017-05-18 08:27:28 -04:00
|
|
|
WayHandlers.default_mode,
|
2016-11-17 07:56:17 -05:00
|
|
|
|
2017-01-23 15:23:33 -05:00
|
|
|
-- check various tags that could indicate that the way is not
|
|
|
|
-- routable. this includes things like status=impassable,
|
|
|
|
-- toll=yes and oneway=reversible
|
2017-05-18 08:27:28 -04:00
|
|
|
WayHandlers.blocked_ways,
|
2017-12-06 05:32:38 -05:00
|
|
|
WayHandlers.avoid_ways,
|
2017-08-14 10:29:38 -04:00
|
|
|
WayHandlers.handle_height,
|
|
|
|
WayHandlers.handle_width,
|
2018-06-06 07:50:48 -04:00
|
|
|
WayHandlers.handle_length,
|
|
|
|
WayHandlers.handle_weight,
|
2016-11-17 07:56:17 -05:00
|
|
|
|
2017-01-23 15:23:33 -05:00
|
|
|
-- determine access status by checking our hierarchy of
|
|
|
|
-- access tags, e.g: motorcar, motor_vehicle, vehicle
|
2017-05-18 08:27:28 -04:00
|
|
|
WayHandlers.access,
|
2016-11-17 07:56:17 -05:00
|
|
|
|
2017-02-03 07:46:28 -05:00
|
|
|
-- check whether forward/backward directions are routable
|
2017-05-18 08:27:28 -04:00
|
|
|
WayHandlers.oneway,
|
2016-11-18 14:49:51 -05:00
|
|
|
|
2017-06-29 16:12:25 -04:00
|
|
|
-- check a road's destination
|
2017-05-18 08:27:28 -04:00
|
|
|
WayHandlers.destinations,
|
2016-11-17 07:56:17 -05:00
|
|
|
|
2017-01-23 15:23:33 -05:00
|
|
|
-- check whether we're using a special transport mode
|
2017-05-18 08:27:28 -04:00
|
|
|
WayHandlers.ferries,
|
|
|
|
WayHandlers.movables,
|
2016-11-17 07:56:17 -05:00
|
|
|
|
2017-01-23 15:23:33 -05:00
|
|
|
-- handle service road restrictions
|
2017-05-18 08:27:28 -04:00
|
|
|
WayHandlers.service,
|
2016-11-17 07:56:17 -05:00
|
|
|
|
2017-02-14 06:59:16 -05:00
|
|
|
-- handle hov
|
2017-05-18 08:27:28 -04:00
|
|
|
WayHandlers.hov,
|
2016-11-17 07:56:17 -05:00
|
|
|
|
2017-01-23 15:23:33 -05:00
|
|
|
-- compute speed taking into account way type, maxspeed tags, etc.
|
2017-05-18 08:27:28 -04:00
|
|
|
WayHandlers.speed,
|
|
|
|
WayHandlers.maxspeed,
|
Process maxspeed tag before surface, smoothness, and tracktype tags (#6002)
* Handle maxspeed tags before surface and smoothness tags
Let's say we have a tertiary road with the following tags:
highway=tertiary
maxspeed=60
surface=gravel
smoothness=intermediate
While the maxspeed tag tells us the legal speed limit, the surface and
smoothness tags have much more effect on the real-world speed of a car.
We should process the maxspeed tags first, and then update the road's
forwards/backwards speeds according to any surface and smoothness tags.
For our hypothetical road the process in the car.lua profile now goes
like this:
1. Get default speed from profile (tertiary = 40 on line 150 of car.lua)
2. Change speed to 60 using maxspeed tag (WayHandlers.maxspeed function
in way_handlers.lua, lines 434-447)
3. Change speed to 40 using surface tag (WayHandlers.surface function
in way_handlers.lua, lines 360-363)
4. Check speed according to smoothness tag --- but because it's higher
than the speed according to the surface tag, leave the speed
unchanged (WayHandlers.surface function again, lines 368-371)
<https://github.com/Project-OSRM/osrm-backend/blob/ec36319232f6b6558080c5586d21fc0bd150de44/profiles/car.lua#L150>
<https://github.com/Project-OSRM/osrm-backend/blob/ec36319232f6b6558080c5586d21fc0bd150de44/profiles/lib/way_handlers.lua#L354-L372>
Note in step 3 above the speed's only changed from 60kph to 40kph
because it's a lower value. If the surface speed was higher than than
the previous value, the speed would remain unchanged. Another example:
highway=tertiary
maxspeed=60
surface=compacted
smoothness=intermediate
Here, although the profile's speed for compacted is 80, it would stay at
the lower value of 60 (see way_handlers.lua, lines 360-363).
<https://github.com/Project-OSRM/osrm-backend/blob/ec36319232f6b6558080c5586d21fc0bd150de44/profiles/lib/way_handlers.lua#L360-L363>
2021-06-03 12:56:57 -04:00
|
|
|
WayHandlers.surface,
|
2017-05-18 08:27:28 -04:00
|
|
|
WayHandlers.penalties,
|
2016-11-17 07:56:17 -05:00
|
|
|
|
2017-06-27 18:01:05 -04:00
|
|
|
-- compute class labels
|
2017-05-18 08:27:28 -04:00
|
|
|
WayHandlers.classes,
|
2017-06-27 18:01:05 -04:00
|
|
|
|
2017-01-23 15:23:33 -05:00
|
|
|
-- handle turn lanes and road classification, used for guidance
|
2017-05-18 08:27:28 -04:00
|
|
|
WayHandlers.turn_lanes,
|
|
|
|
WayHandlers.classification,
|
2016-11-17 07:56:17 -05:00
|
|
|
|
2017-01-23 15:23:33 -05:00
|
|
|
-- handle various other flags
|
2017-05-18 08:27:28 -04:00
|
|
|
WayHandlers.roundabouts,
|
|
|
|
WayHandlers.startpoint,
|
2017-08-15 10:53:27 -04:00
|
|
|
WayHandlers.driving_side,
|
2016-11-17 07:56:17 -05:00
|
|
|
|
2017-01-23 15:23:33 -05:00
|
|
|
-- set name, ref and pronunciation
|
2017-05-18 08:27:28 -04:00
|
|
|
WayHandlers.names,
|
2017-02-01 14:35:29 -05:00
|
|
|
|
|
|
|
-- set weight properties of the way
|
2018-01-24 15:39:55 -05:00
|
|
|
WayHandlers.weights,
|
|
|
|
|
|
|
|
-- set classification of ways relevant for turns
|
|
|
|
WayHandlers.way_classification_for_turn
|
2017-01-23 15:23:33 -05:00
|
|
|
}
|
2017-02-01 14:35:29 -05:00
|
|
|
|
2017-09-22 08:03:12 -04:00
|
|
|
WayHandlers.run(profile, way, result, data, handlers, relations)
|
2017-09-05 09:41:55 -04:00
|
|
|
|
2017-10-24 20:21:08 -04:00
|
|
|
if profile.cardinal_directions then
|
|
|
|
Relations.process_way_refs(way, relations, result)
|
|
|
|
end
|
2012-09-27 05:35:56 -04:00
|
|
|
end
|
2012-11-03 03:19:01 -04:00
|
|
|
|
2017-07-19 09:32:42 -04:00
|
|
|
function process_turn(profile, turn)
|
2016-09-06 12:07:00 -04:00
|
|
|
-- 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.
|
2017-01-23 15:23:33 -05:00
|
|
|
local turn_penalty = profile.turn_penalty
|
2017-08-15 10:53:27 -04:00
|
|
|
local turn_bias = turn.is_left_hand_driving and 1. / profile.turn_bias or profile.turn_bias
|
2017-02-01 14:35:29 -05:00
|
|
|
|
2017-04-19 10:47:35 -04:00
|
|
|
if turn.has_traffic_light then
|
2017-05-18 08:27:28 -04:00
|
|
|
turn.duration = profile.properties.traffic_light_penalty
|
2017-04-19 10:47:35 -04:00
|
|
|
end
|
|
|
|
|
2017-11-03 13:30:46 -04:00
|
|
|
if turn.number_of_roads > 2 or turn.source_mode ~= turn.target_mode or turn.is_u_turn then
|
2016-05-12 12:50:10 -04:00
|
|
|
if turn.angle >= 0 then
|
2017-04-19 10:47:35 -04:00
|
|
|
turn.duration = turn.duration + turn_penalty / (1 + math.exp( -((13 / turn_bias) * turn.angle/180 - 6.5*turn_bias)))
|
2016-05-12 12:50:10 -04:00
|
|
|
else
|
2017-04-19 10:47:35 -04:00
|
|
|
turn.duration = turn.duration + turn_penalty / (1 + math.exp( -((13 * turn_bias) * -turn.angle/180 - 6.5/turn_bias)))
|
2016-05-12 12:50:10 -04:00
|
|
|
end
|
|
|
|
|
2017-11-03 13:30:46 -04:00
|
|
|
if turn.is_u_turn then
|
2017-05-18 08:27:28 -04:00
|
|
|
turn.duration = turn.duration + profile.properties.u_turn_penalty
|
2016-05-12 12:50:10 -04:00
|
|
|
end
|
2017-07-03 06:18:35 -04:00
|
|
|
end
|
2016-05-12 12:50:10 -04:00
|
|
|
|
2017-07-03 06:18:35 -04:00
|
|
|
-- for distance based routing we don't want to have penalties based on turn angle
|
2017-05-18 08:27:28 -04:00
|
|
|
if profile.properties.weight_name == 'distance' then
|
2017-07-03 06:18:35 -04:00
|
|
|
turn.weight = 0
|
|
|
|
else
|
|
|
|
turn.weight = turn.duration
|
2017-03-01 13:50:53 -05:00
|
|
|
end
|
2017-07-19 09:32:42 -04:00
|
|
|
|
2017-05-18 08:27:28 -04:00
|
|
|
if profile.properties.weight_name == 'routability' then
|
2017-03-01 13:50:53 -05:00
|
|
|
-- penalize turns from non-local access only segments onto local access only tags
|
|
|
|
if not turn.source_restricted and turn.target_restricted then
|
2017-05-18 08:27:28 -04:00
|
|
|
turn.weight = constants.max_turn_weight
|
2017-03-01 13:50:53 -05:00
|
|
|
end
|
2015-08-30 13:17:19 -04:00
|
|
|
end
|
|
|
|
end
|
2017-05-18 08:27:28 -04:00
|
|
|
|
|
|
|
return {
|
|
|
|
setup = setup,
|
|
|
|
process_way = process_way,
|
|
|
|
process_node = process_node,
|
|
|
|
process_turn = process_turn
|
|
|
|
}
|