-- This example shows how to query external data stored in PostGIS when processing ways. -- This profile assumes that OSM data has been imported to PostGIS using imposm to a db -- with the name 'imposm', the default user and no password. It assumes areas with -- landusage=* was imported to the table osm_landusages, containting the columns type and area. -- Seee http://imposm.org/ for more info on imposm. -- Other tools for importing OSM data to PostGIS include osm2pgsql and osmosis. -- It uses the PostGIS function ST_DWithin() to find areas tagged with landuse=industrial -- that are within 100 meters of the way. -- It then slows down the routing depending on the number and size of the industrial area. -- The end result is that routes will tend to avoid industrial area. Passing through -- industrial areas is still possible, it's just slower, and thus avoided if a reasonable -- alternative is found. -- We use the osm id as the key when querying PostGIS. Be sure to add an index to the colunn -- containing the osm id (osm_id in this case), otherwise you will suffer form very -- bad performance. You should also have spatial indexes on the relevant gemoetry columns. -- More info about using SQL form LUA can be found at http://www.keplerproject.org/luasql/ -- Happy routing! -- Open PostGIS connection lua_sql = require "luasql.postgres" -- we will connect to a postgresql database sql_env = assert( lua_sql.postgres() ) sql_con = assert( sql_env:connect("imposm") ) -- you can add db user/password here if needed print("PostGIS connection opened") -- these settings are read directly by osrm take_minimum_of_speeds = true obey_oneway = true use_restrictions = true ignore_areas = true -- future feature traffic_signal_penalty = 7 -- seconds -- nodes processing, called from OSRM function node_function(node) return 1 end -- ways processing, called from OSRM function way_function (way, result) -- only route on ways with highway=* local highway = way.tags:Find("highway") if (not highway or highway=='') then return 0 end -- Query PostGIS for industrial areas close to the way, then group by way and sum the areas. -- We take the square root of the area to get a estimate of the length of the side of the area, -- and thus a rough guess of how far we might be travelling along the area. local sql_query = " " .. "SELECT SUM(SQRT(area.area)) AS val " .. "FROM osm_ways way " .. "LEFT JOIN osm_landusages area ON ST_DWithin(way.geometry, area.geometry, 100) " .. "WHERE area.type IN ('industrial') AND way.osm_id=" .. way.id .. " " .. "GROUP BY way.id" local cursor = assert( sql_con:execute(sql_query) ) -- execute querty local row = cursor:fetch( {}, "a" ) -- fetch first (and only) row result.forward_speed = 20.0 -- default speed result.forward_mode = 1 if row then local val = tonumber(row.val) -- read 'val' from row if val > 10 then -- reduce speed by amount of industry close by result.forward_speed = way.forward_speed / math.log10( val ) end end cursor:close() -- done with this query -- set other required info for this way result.name = way.get_value_by_key("name") return 1 end