361 lines
10 KiB
Lua
361 lines
10 KiB
Lua
|
|
-- Foot profile
|
|
local http = require("socket.http") -- LuaSocket for HTTP requests
|
|
local json = require("cjson")
|
|
|
|
api_version = 2
|
|
|
|
Set = require('lib/set')
|
|
Sequence = require('lib/sequence')
|
|
Handlers = require("lib/way_handlers")
|
|
find_access_tag = require("lib/access").find_access_tag
|
|
stations_data = nil
|
|
|
|
|
|
function fetch_pollution_data()
|
|
local url = "http://128.199.51.173:8000/routes/api/pollution/PM10"
|
|
local response, status = http.request(url)
|
|
|
|
if status == 200 and response then
|
|
print("Raw response:", response)
|
|
local success, data = pcall(json.decode, response) -- Manejar errores de JSON
|
|
if success and data and data.stations then
|
|
print("Pollution data fetched successfully.")
|
|
print("Number of stations:", #data.stations)
|
|
return data
|
|
else
|
|
print("Failed to decode JSON or missing 'stations' key.")
|
|
end
|
|
else
|
|
print("HTTP request failed. Status:", status)
|
|
end
|
|
|
|
-- Fallback a datos vacíos si hay un error
|
|
return { stations = {} }
|
|
end
|
|
|
|
|
|
|
|
function setup()
|
|
local walking_speed = 5
|
|
stations_data = fetch_pollution_data()
|
|
|
|
-- Check if data was successfully retrieved
|
|
if not stations_data or not stations_data.stations then
|
|
print("Warning: Pollution data could not be loaded. Defaulting to no pollution.")
|
|
stations_data = { stations = {} } -- Fallback to empty station data
|
|
else
|
|
print("Pollution data loaded successfully.")
|
|
end
|
|
return {
|
|
properties = {
|
|
weight_name = 'duration',
|
|
max_speed_for_map_matching = 40/3.6, -- kmph -> m/s
|
|
call_tagless_node_function = false,
|
|
traffic_light_penalty = 2,
|
|
u_turn_penalty = 2,
|
|
continue_straight_at_waypoint = false,
|
|
use_turn_restrictions = false,
|
|
},
|
|
|
|
default_mode = mode.walking,
|
|
default_speed = walking_speed,
|
|
oneway_handling = 'specific', -- respect 'oneway:foot' but not 'oneway'
|
|
|
|
barrier_blacklist = Set {
|
|
'yes',
|
|
'wall',
|
|
'fence'
|
|
},
|
|
|
|
access_tag_whitelist = Set {
|
|
'yes',
|
|
'foot',
|
|
'permissive',
|
|
'designated'
|
|
},
|
|
|
|
access_tag_blacklist = Set {
|
|
'no',
|
|
'agricultural',
|
|
'forestry',
|
|
'private',
|
|
'delivery',
|
|
},
|
|
|
|
restricted_access_tag_list = Set { },
|
|
|
|
restricted_highway_whitelist = Set { },
|
|
|
|
construction_whitelist = Set {},
|
|
|
|
access_tags_hierarchy = Sequence {
|
|
'foot',
|
|
'access'
|
|
},
|
|
|
|
-- tags disallow access to in combination with highway=service
|
|
service_access_tag_blacklist = Set { },
|
|
|
|
restrictions = Sequence {
|
|
'foot'
|
|
},
|
|
|
|
-- list of suffixes to suppress in name change instructions
|
|
suffix_list = Set {
|
|
'N', 'NE', 'E', 'SE', 'S', 'SW', 'W', 'NW', 'North', 'South', 'West', 'East'
|
|
},
|
|
|
|
avoid = Set {
|
|
'impassable',
|
|
'proposed'
|
|
},
|
|
|
|
speeds = Sequence {
|
|
highway = {
|
|
primary = walking_speed,
|
|
primary_link = walking_speed,
|
|
secondary = walking_speed,
|
|
secondary_link = walking_speed,
|
|
tertiary = walking_speed,
|
|
tertiary_link = walking_speed,
|
|
unclassified = walking_speed,
|
|
residential = walking_speed,
|
|
road = walking_speed,
|
|
living_street = walking_speed,
|
|
service = walking_speed,
|
|
track = walking_speed,
|
|
path = walking_speed,
|
|
steps = walking_speed,
|
|
pedestrian = walking_speed,
|
|
platform = walking_speed,
|
|
footway = walking_speed,
|
|
pier = walking_speed,
|
|
},
|
|
|
|
railway = {
|
|
platform = walking_speed
|
|
},
|
|
|
|
amenity = {
|
|
parking = walking_speed,
|
|
parking_entrance= walking_speed
|
|
},
|
|
|
|
man_made = {
|
|
pier = walking_speed
|
|
},
|
|
|
|
leisure = {
|
|
track = walking_speed
|
|
}
|
|
},
|
|
|
|
route_speeds = {
|
|
ferry = 5
|
|
},
|
|
|
|
bridge_speeds = {
|
|
},
|
|
|
|
surface_speeds = {
|
|
fine_gravel = walking_speed*0.75,
|
|
gravel = walking_speed*0.75,
|
|
pebblestone = walking_speed*0.75,
|
|
mud = walking_speed*0.5,
|
|
sand = walking_speed*0.5
|
|
},
|
|
|
|
tracktype_speeds = {
|
|
},
|
|
|
|
smoothness_speeds = {
|
|
}
|
|
}
|
|
end
|
|
|
|
function calculate_pollution(lat, lon)
|
|
-- Calcular contaminación
|
|
local pollution_value = 0
|
|
local total_weight = 0
|
|
local weight = 0
|
|
local p = 1.8
|
|
local max_distance = 3
|
|
if stations_data and stations_data.stations then
|
|
for _, station in ipairs(stations_data.stations) do
|
|
local station_lat = tonumber(station.lat)
|
|
local station_lon = tonumber(station.lon)
|
|
local latest_reading = tonumber(station.pollution)
|
|
|
|
if station_lat and station_lon and latest_reading then
|
|
-- Fórmula de distancia usando Haversine
|
|
local R = 6371 -- Radio de la Tierra en km
|
|
local dlat = math.rad(station_lat - lat)
|
|
local dlon = math.rad(station_lon - lon)
|
|
local a = math.sin(dlat / 2)^2 +
|
|
math.cos(math.rad(lat)) * math.cos(math.rad(station_lat)) * math.sin(dlon / 2)^2
|
|
local c = 2 * math.atan2(math.sqrt(a), math.sqrt(1 - a))
|
|
local distance = R * c
|
|
|
|
-- Ponderación ajustada
|
|
weight = 1 / ((distance + 1))
|
|
weight = tonumber(string.format("%.6f", weight))
|
|
pollution_value = pollution_value + (latest_reading * weight)
|
|
--total_weight = total_weight + weight
|
|
|
|
end
|
|
end
|
|
--print(pollution_value)
|
|
return pollution_value
|
|
else
|
|
print("No station data available.")
|
|
return 0
|
|
end
|
|
end
|
|
|
|
function process_node(profile, 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 profile.barrier_blacklist[barrier] and not rising_bollard then
|
|
result.barrier = true
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
|
|
-- main entry point for processsing a way
|
|
function process_way(profile, 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"),
|
|
}
|
|
|
|
-- Verificar si el objeto `way` está definido
|
|
if not way then
|
|
print("Error: way is nil.")
|
|
return
|
|
end
|
|
|
|
|
|
-- perform an quick initial check and abort if the way is
|
|
-- obviously not routable. here we require at least one
|
|
-- of the prefetched tags to be present, ie. the data table
|
|
-- cannot be empty
|
|
if next(data) == nil then -- is the data table empty?
|
|
return
|
|
end
|
|
|
|
local 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
|
|
WayHandlers.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
|
|
WayHandlers.blocked_ways,
|
|
|
|
-- determine access status by checking our hierarchy of
|
|
-- access tags, e.g: motorcar, motor_vehicle, vehicle
|
|
WayHandlers.access,
|
|
|
|
-- check whether forward/backward directons are routable
|
|
WayHandlers.oneway,
|
|
|
|
-- check whether forward/backward directons are routable
|
|
WayHandlers.destinations,
|
|
|
|
-- check whether we're using a special transport mode
|
|
WayHandlers.ferries,
|
|
WayHandlers.movables,
|
|
|
|
-- compute speed taking into account way type, maxspeed tags, etc.
|
|
WayHandlers.speed,
|
|
WayHandlers.surface,
|
|
|
|
-- handle turn lanes and road classification, used for guidance
|
|
WayHandlers.classification,
|
|
|
|
-- handle various other flags
|
|
WayHandlers.roundabouts,
|
|
WayHandlers.startpoint,
|
|
|
|
-- set name, ref and pronunciation
|
|
WayHandlers.names,
|
|
|
|
-- set weight properties of the way
|
|
WayHandlers.weights,
|
|
}
|
|
|
|
WayHandlers.run(profile, way, result, data, handlers)
|
|
end
|
|
|
|
function process_turn (profile, turn)
|
|
turn.duration = 0.
|
|
|
|
if turn.direction_modifier == direction_modifier.u_turn then
|
|
turn.duration = turn.duration + profile.properties.u_turn_penalty
|
|
end
|
|
|
|
if turn.has_traffic_light then
|
|
turn.duration = profile.properties.traffic_light_penalty
|
|
end
|
|
if profile.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 + 3000
|
|
end
|
|
end
|
|
end
|
|
|
|
function process_segment(profile, segment)
|
|
-- Extract coordinates of the start and end points
|
|
local source_lat, source_lon = segment.source.lat, segment.source.lon
|
|
local target_lat, target_lon = segment.target.lat, segment.target.lon
|
|
|
|
-- Calculate pollution impact at source and target
|
|
local pollution_source = calculate_pollution(source_lat, source_lon)
|
|
local pollution_target = calculate_pollution(target_lat, target_lon)
|
|
|
|
|
|
-- Average pollution for the segment
|
|
local avg_pollution = (pollution_source + pollution_target) / 2
|
|
--print(avg_pollution)
|
|
|
|
-- Adjust weight and duration based on pollution level
|
|
segment.weight = segment.weight + (avg_pollution^1.4)
|
|
end
|
|
|
|
|
|
return {
|
|
setup = setup,
|
|
process_way = process_way,
|
|
process_node = process_node,
|
|
process_turn = process_turn,
|
|
process_segment = process_segment
|
|
}
|