Skip to content

Commit

Permalink
add new car profile and libs for unidb (#214)
Browse files Browse the repository at this point in the history
* add new car profile and libs for unidb

* Add an empty README file to log rules and changes

* Remove README.md for this pr, will add it back in coming pr
  • Loading branch information
hellotechx authored Mar 11, 2020
1 parent 852f27e commit c0c85e2
Show file tree
Hide file tree
Showing 14 changed files with 2,649 additions and 0 deletions.
503 changes: 503 additions & 0 deletions profiles/car-unidb.lua

Large diffs are not rendered by default.

15 changes: 15 additions & 0 deletions profiles/lib-unidb/access.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
local ipairs = ipairs

local Access = {}

function Access.find_access_tag(source,access_tags_hierarchy)
for i,v in ipairs(access_tags_hierarchy) do
local tag = source:get_value_by_key(v)
if tag then
return tag
end
end
return nil
end

return Access
29 changes: 29 additions & 0 deletions profiles/lib-unidb/destination.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
local Destination = {}

function Destination.get_directional_tag(way, is_forward, tag)
local v
if is_forward then
v = way:get_value_by_key(tag .. ':forward') or way:get_value_by_key(tag)
else
v = way:get_value_by_key(tag .. ':backward') or way:get_value_by_key(tag)
end
if v then
return v.gsub(v, ';', ', ')
end
end

-- Assemble destination as: "A59: Düsseldorf, Köln"
-- destination:ref ^ ^ destination

function Destination.get_destination(way, is_forward)
ref = Destination.get_directional_tag(way, is_forward, 'destination:ref')
dest = Destination.get_directional_tag(way, is_forward, 'destination')
street = Destination.get_directional_tag(way, is_forward, 'destination:street')
if ref and dest then
return ref .. ': ' .. dest
else
return ref or dest or street or ''
end
end

return Destination
173 changes: 173 additions & 0 deletions profiles/lib-unidb/guidance.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,173 @@
local Tags = require('lib-unidb/tags')
local Set = require('lib-unidb/set')

local Guidance = {}

-- Guidance: Default Mapping from roads to types/priorities
highway_classes = {
motorway = road_priority_class.motorway,
motorway_link = road_priority_class.motorway_link,
trunk = road_priority_class.trunk,
trunk_link = road_priority_class.trunk_link,
primary = road_priority_class.primary,
primary_link = road_priority_class.primary_link,
secondary = road_priority_class.secondary,
secondary_link = road_priority_class.secondary_link,
tertiary = road_priority_class.tertiary,
tertiary_link = road_priority_class.tertiary_link,
unclassified = road_priority_class.unclassified,
residential = road_priority_class.main_residential,
service = road_priority_class.alley,
living_street = road_priority_class.side_residential,
track = road_priority_class.bike_path,
path = road_priority_class.bike_path,
footway = road_priority_class.foot_path,
pedestrian = road_priority_class.foot_path,
steps = road_priority_class.foot_path
}

default_highway_class = road_priority_class.connectivity;

motorway_types = Set {
'motorway',
'motorway_link',
'trunk',
'trunk_link'
}

-- these road types are set with a car in mind. For bicycle/walk we probably need different ones
road_types = Set {
'motorway',
'motorway_link',
'trunk',
'trunk_link',
'primary',
'primary_link',
'secondary',
'secondary_link',
'tertiary',
'tertiary_link',
'unclassified',
'residential',
'living_street'
}

link_types = Set {
'motorway_link',
'trunk_link',
'primary_link',
'secondary_link',
'tertiary_link'
}

-- roads like parking lots are very unimportant for normal driving
parking_class = Set{
'parking_aisle',
'driveway',
'drive-through',
'emergency_access'
}

function Guidance.set_classification (highway, result, input_way)
if motorway_types[highway] then
result.road_classification.motorway_class = true
end
if link_types[highway] then
result.road_classification.link_class = true
end

-- All service roads are recognised as alley
if highway ~= nil and highway == 'service' then
local service_type = input_way:get_value_by_key('service');
if service_type ~= nil and parking_class[service_type] then
result.road_classification.road_priority_class = road_priority_class.alley
else
if service_type ~= nil and service_type == 'alley' then
result.road_classification.road_priority_class = road_priority_class.alley
else
if serice_type == nil then
result.road_classification.road_priority_class = road_priority_class.alley
else
result.road_classification.road_priority_class = highway_classes[highway]
end
end
end
else
if highway_classes[highway] ~= nil then
result.road_classification.road_priority_class = highway_classes[highway]
else
result.road_classification.road_priority_class = default_highway_class
end
end
if road_types[highway] then
result.road_classification.may_be_ignored = false;
else
result.road_classification.may_be_ignored = true;
end

local lane_count = input_way:get_value_by_key("lanes")
if lane_count then
local lc = tonumber(lane_count)
if lc ~= nil then
result.road_classification.num_lanes = lc
end
else
local total_count = 0
local forward_count = input_way:get_value_by_key("lanes:forward")
if forward_count then
local fc = tonumber(forward_count)
if fc ~= nil then
total_count = fc
end
end
local backward_count = input_way:get_value_by_key("lanes:backward")
if backward_count then
local bc = tonumber(backward_count)
if bc ~= nil then
total_count = total_count + bc
end
end
if total_count ~= 0 then
result.road_classification.num_lanes = total_count
end
end
end

-- returns forward,backward psv lane count
local function get_psv_counts(way,data)
local psv_forward, psv_backward = Tags.get_forward_backward_by_key(way,data,'lanes:psv')
if psv_forward then
psv_forward = tonumber(psv_forward)
end
if psv_backward then
psv_backward = tonumber(psv_backward)
end
return psv_forward or 0,
psv_backward or 0
end

-- trims lane string with regard to supported lanes
local function process_lanes(turn_lanes,vehicle_lanes,first_count,second_count)
if turn_lanes then
if vehicle_lanes then
return applyAccessTokens(turn_lanes,vehicle_lanes)
elseif first_count ~= 0 or second_count ~= 0 then
return trimLaneString(turn_lanes, first_count, second_count)
else
return turn_lanes
end
end
end

-- this is broken for left-sided driving. It needs to switch left and right in case of left-sided driving
function Guidance.get_turn_lanes(way,data)
local psv_fw, psv_bw = get_psv_counts(way,data)
local turn_lanes_fw, turn_lanes_bw = Tags.get_forward_backward_by_key(way,data,'turn:lanes')
local vehicle_lanes_fw, vehicle_lanes_bw = Tags.get_forward_backward_by_key(way,data,'vehicle:lanes')

--note: backward lanes swap psv_bw and psv_fw
return process_lanes(turn_lanes_fw,vehicle_lanes_fw,psv_bw,psv_fw) or turn_lanes,
process_lanes(turn_lanes_bw,vehicle_lanes_bw,psv_fw,psv_bw) or turn_lanes
end

return Guidance
19 changes: 19 additions & 0 deletions profiles/lib-unidb/maxspeed.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
local math = math

local MaxSpeed = {}

function MaxSpeed.limit(way,max,maxf,maxb)
if maxf and maxf>0 then
way.forward_speed = math.min(way.forward_speed, maxf)
elseif max and max>0 then
way.forward_speed = math.min(way.forward_speed, max)
end

if maxb and maxb>0 then
way.backward_speed = math.min(way.backward_speed, maxb)
elseif max and max>0 then
way.backward_speed = math.min(way.backward_speed, max)
end
end

return MaxSpeed
111 changes: 111 additions & 0 deletions profiles/lib-unidb/measure.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
local Sequence = require('lib-unidb/sequence')
local Sequence = require('lib-unidb/set')

Measure = {}

-- measurements conversion constants
local inch_to_meters = 0.0254
local feet_to_inches = 12
local pound_to_kilograms = 0.45359237
local miles_to_kilometers = 1.609

-- Parse speed value as kilometers by hours.
function Measure.parse_value_speed(source, speed_unit)
local n = tonumber(source:match("%d*"))
if n then
if string.match(source, "mph") or string.match(source, "mp/h") then
n = n * miles_to_kilometers
elseif speed_unit and speed_unit == "M" then
n = n * miles_to_kilometers
end

return n
end
end

--- Parse string as a height in meters.
--- according to http://wiki.openstreetmap.org/wiki/Key:maxheight
function Measure.parse_value_meters(value)
local n = tonumber(value:gsub(",", "."):match("%d+%.?%d*"))
if n then
inches = value:match("'.*")
if inches then -- Imperial unit to metric
-- try to parse feets/inch
n = n * feet_to_inches
local m = tonumber(inches:match("%d+"))
if m then
n = n + m
end
n = n * inch_to_meters
end
return n
end
end

--- Parse weight value in kilograms.
--- according to https://wiki.openstreetmap.org/wiki/Key:maxweight
function Measure.parse_value_kilograms(value)
local n = tonumber(value:gsub(",", "."):match("%d+%.?%d*"))
if n then
if string.match(value, "lbs") then
n = n * pound_to_kilograms
elseif string.match(value, "kg") then
-- n = n
else -- Default, metric tons
n = n * 1000
end
return n
end
end

--- Get maxspeed of specified way in kilometers by hours.
function Measure.get_max_speed(raw_value, speed_unit)
if raw_value then
return Measure.parse_value_speed(raw_value, speed_unit)
end
end

-- default maxheight value defined in https://wiki.openstreetmap.org/wiki/Key:maxheight#Non-numerical_values
local default_maxheight = 4.5
-- Available Non numerical values equal to 4.5; below_default and no_indications are not considered
local height_non_numerical_values = Set { "default", "none", "no-sign", "unsigned" }

--- Get maxheight of specified way in meters. If there are no
--- max height, then return nil
function Measure.get_max_height(raw_value, element)
if raw_value then
if height_non_numerical_values[raw_value] then
if element then
return element:get_location_tag('maxheight') or default_maxheight
else
return default_maxheight
end
else
return Measure.parse_value_meters(raw_value)
end
end
end

--- Get maxwidth of specified way in meters.
function Measure.get_max_width(raw_value)
if raw_value then
return Measure.parse_value_meters(raw_value)
end
end

--- Get maxlength of specified way in meters.
function Measure.get_max_length(raw_value)
if raw_value then
return Measure.parse_value_meters(raw_value)
end
end

--- Get maxweight of specified way in kilogramms.
function Measure.get_max_weight(raw_value)
if raw_value then
return Measure.parse_value_kilograms(raw_value)
end
end


return Measure;
Loading

0 comments on commit c0c85e2

Please sign in to comment.