-- enduro.lua — OSRM профиль для эндуро-роутинга "Дикий путь" -- Стратегия: weight = distance_meters * penalty -- Грунтовки penalty=1, асфальт penalty=10+ -- OSRM минимизирует суммарный weight → выбирает грунтовки api_version = 4 -- Штраф за метр пути (меньше = предпочтительнее) -- Грунтовки ~1, асфальт ~10+ local highway_penalty = { track = 1.0, bridleway = 1.2, path = 1.3, cycleway = 1.5, footway = 2.0, unclassified = 3.0, residential = 5.0, service = 6.0, tertiary = 12.0, tertiary_link= 12.0, secondary = 18.0, secondary_link = 18.0, primary = 25.0, primary_link = 25.0, trunk = 40.0, trunk_link = 40.0, motorway = 999.0, motorway_link= 999.0, } -- Скорости (км/ч) — только для ETA, не влияют на выбор маршрута local highway_speeds = { track = 30, bridleway = 20, path = 20, cycleway = 25, footway = 15, unclassified = 40, residential = 40, service = 30, tertiary = 60, tertiary_link= 60, secondary = 60, secondary_link = 60, primary = 60, primary_link = 60, trunk = 60, trunk_link = 60, motorway = 90, motorway_link= 90, } -- Мультипликатор по качеству грунтовки (grade1=лучший, grade5=тяжёлый) local tracktype_multiplier = { grade1 = 1.0, grade2 = 1.1, grade3 = 1.2, grade4 = 1.4, grade5 = 1.6, } function setup() return { properties = { weight_name = 'duration', max_speed_for_map_matching = 30/3.6, call_tagless_node_function = false, traffic_light_penalty = 2, u_turn_penalty = 20, continue_straight_at_waypoint = false, use_turn_restrictions = false, } } end function process_node(profile, node, result) local barrier = node:get_value_by_key("barrier") if barrier == "gate" or barrier == "bollard" or barrier == "lift_gate" then result.barrier = true end end function process_way(profile, way, result) local highway = way:get_value_by_key("highway") if not highway then return end local penalty = highway_penalty[highway] if not penalty then return end local speed = highway_speeds[highway] or 30 -- Мультипликатор по tracktype для грунтовок local tracktype = way:get_value_by_key("tracktype") if tracktype and tracktype_multiplier[tracktype] then penalty = penalty * tracktype_multiplier[tracktype] end result.forward_mode = mode.driving result.backward_mode = mode.driving result.forward_speed = speed result.backward_speed = speed -- duration = реальное время (секунды) — используется для ETA -- weight = штраф для роутера — грунтовки дешевле асфальта -- Задаём rate: weight_per_meter = penalty / speed_mps -- OSRM считает weight = rate * distance local speed_mps = speed / 3.6 result.forward_rate = penalty / speed_mps result.backward_rate = penalty / speed_mps -- Одностороннее движение local oneway = way:get_value_by_key("oneway") if oneway == "yes" or oneway == "1" or oneway == "true" then result.backward_mode = mode.inaccessible elseif oneway == "-1" then result.forward_mode = mode.inaccessible end end function process_turn(profile, turn) turn.duration = 0 turn.weight = 0 if turn.is_u_turn then turn.duration = profile.properties.u_turn_penalty turn.weight = profile.properties.u_turn_penalty end end return { setup = setup, process_way = process_way, process_node = process_node, process_turn = process_turn, }