-- enduro.lua — OSRM профиль для эндуро-роутинга "Дикий путь" -- Логика: weight = distance / forward_rate -- Чтобы грунтовки были ДЕШЕВЛЕ асфальта → у грунтовок forward_rate БОЛЬШЕ -- (высокий rate → маленький weight на тот же distance) -- У асфальта forward_rate МЕНЬШЕ → большой weight → OSRM избегает -- Обновлён: 2026-05-15 (ET-001: блокировка шлагбаумов через mode.inaccessible, -- исключение footway/pedestrian/steps/corridor из графа) api_version = 4 -- forward_rate: чем ВЫШЕ — тем ПРЕДПОЧТИТЕЛЬНЕЕ маршрут -- грунтовки = высокий rate (предпочтительны) -- асфальт = низкий rate (избегаем, но штраф 3-5x вместо 17-200x) -- Примечание: footway/pedestrian/steps/corridor отсутствуют — они полностью исключены -- из графа в process_way (ET-001, F-08). local highway_rate = { track = 100.0, -- самый предпочтительный bridleway = 90.0, path = 85.0, cycleway = 70.0, unclassified = 45.0, residential = 35.0, service = 28.0, tertiary = 28.0, -- было 6.0 → теперь ~3.5x хуже track tertiary_link= 28.0, secondary = 22.0, -- было 3.0 → теперь ~4.5x хуже track secondary_link = 22.0, primary = 18.0, -- было 1.5 → теперь ~5.5x хуже track primary_link = 18.0, trunk = 12.0, -- было 0.5 trunk_link = 12.0, motorway = 5.0, -- было 0.1 motorway_link= 5.0, } -- Скорости (км/ч) — только для ETA (duration), не влияют на выбор маршрута local highway_speeds = { track = 30, bridleway = 20, path = 20, cycleway = 25, unclassified = 40, residential = 40, service = 30, tertiary = 60, tertiary_link= 60, secondary = 70, secondary_link = 70, primary = 80, primary_link = 80, trunk = 90, trunk_link = 90, motorway = 110, motorway_link= 90, } -- Мультипликатор по качеству грунтовки (grade1 лучше grade5) local tracktype_multiplier = { grade1 = 1.2, grade2 = 1.1, grade3 = 1.0, grade4 = 0.9, grade5 = 0.8, } -- ET-001 (F-07): полный запрет проезда через ноды-шлагбаумы. -- cattle_grid и ford НЕ включены — мотоцикл их проходит. local blocked_barriers = { gate = true, bollard = true, lift_gate = true, chain = true, cycle_barrier = true, motorcycle_barrier = true, border_control = true, block = true, } -- ET-001 (F-08): пешеходные/служебные типы дорог, полностью исключаемые из графа. local excluded_highways = { footway = true, pedestrian = true, steps = true, corridor = true, } function setup() return { properties = { weight_name = 'routability', 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 -- ET-001 (F-07): шлагбаумы блокируются жёстко через mode.inaccessible. -- Тег access не учитывается — физическое наличие шлагбаума уже причина обхода. function process_node(profile, node, result) local barrier = node:get_value_by_key("barrier") if barrier and blocked_barriers[barrier] then result.barrier = true result.forward_mode = mode.inaccessible result.backward_mode = mode.inaccessible return end end function process_way(profile, way, result) local highway = way:get_value_by_key("highway") if not highway then return end -- ET-001 (F-08): пешеходные/служебные типы — полностью убираем из графа. if excluded_highways[highway] then return end local rate = highway_rate[highway] if not rate then return end -- path/cycleway в городской застройке — исключить if highway == "path" or highway == "cycleway" then local landuse = way:get_value_by_key("landuse") local place = way:get_value_by_key("place") -- Признаки городской застройки if landuse == "residential" or landuse == "commercial" or landuse == "industrial" or place == "city" or place == "town" or place == "village" then return -- исключить из графа end end local speed = highway_speeds[highway] or 30 -- Мультипликатор по tracktype для грунтовок local tracktype = way:get_value_by_key("tracktype") if tracktype and tracktype_multiplier[tracktype] then rate = rate * tracktype_multiplier[tracktype] end result.forward_mode = mode.driving result.backward_mode = mode.driving -- duration = реальное время (скорость в км/ч) result.forward_speed = speed result.backward_speed = speed -- weight = distance / rate -- высокий rate → маленький weight → предпочтительный маршрут result.forward_rate = rate result.backward_rate = rate -- Одностороннее движение 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, }