I'm currently testing pgRouting using OpenStreempMap XML dataset loaded via Osm2PgRouting. My goal is to solve shortest path problems using time driven costs instead of path length.

I noticed that since V 2.1 osm2pgrouting include two nice columns namely cost_s and reverse_cost_s. They aim to express cost in seconds. Theses columns are computed using maxspeed_forward maxspeed_backward properties.

When the OSM dataset include maxspeed attribute you can expect reasonable results. However when theses tags are not filled a default value is applied (controlled by the config.xml file).

This lead to very high maxspeed values in residential area when the road type is set to primary/secondary/tertiary. But 90Km/H inside a town really doesn't sound realistic.

Has anybody already have a fix for that kind of behavior?

I was thinking about setting a lower maxspeed for road that intersect landuse=residential in OSM. Am I reinventing the wheel or is it something to look at?

  • What's wrong with just setting the maxspeed yourself for these roads? That should be very quick. If you have an idea of what a reasonable value should be, and if there is no OSM data on maxspeed, you will probably get better results than using the default.
    – amball
    Commented Sep 20, 2016 at 18:26
  • This is what I'm currently doing. And I'll post my method here if I there is no other answer. Thing is I must not be the only one that stumble into that problem so maybe there is already a known solution out there. Plus in the spirit of OSM the ideal would be to improve the master database so that everybody profit from theses tweaking. This was more like a bottle thrown into the sea. But perhaps my message is unclear feel free to suggest improvement ;)
    – MarHoff
    Commented Sep 21, 2016 at 8:07

1 Answer 1


Here is my quick-fix assuming you have downloaded from OSM all polygon with the tag landuse="residential" in the working area of your network. Thoses polygons are stored under the table "landuse_residential" in my DB.

  1. Intersect the two layers to finds ways in a residential area

    WITH intersect_residential as (
         SELECT distinct(ways.gid) as gid_select FROM ways, landuse_residential
         WHERE ST_Intersects(ways.the_geom,landuse_residential.geom) AND st_isvalid(landuse_residential.geom))
    UPDATE ways SET rule='residential' FROM intersect_residential WHERE gid=gid_select;

    Notice I am storing the result in the ways.rule column because i literally have no other use of it. You may want to create a new column to store result depending on you use case.

  2. Update maxspeed columns according to residential area

    UPDATE ways SET
    WHERE rule='residential' AND class_id NOT IN (101,102,103,104,105);

    I'm setting maxspeed as an upper limit according to my country laws, if a lower limit have been set I got to keep it using LEAST(). Please notice that I exclude road class like motorway & trunk because even if they appear in urban area you can expect that they are ruled by specific speed limit, so it would be very unwise to affect a standard town speed limit.

  3. Update cost_s and reversecost_s according to new max_speeed

    UPDATE ways SET
          cost_s = CASE 
                   WHEN one_way = -1 THEN -st_length(geography(ST_Transform(the_geom, 4326))) / (maxspeed_forward * 5 / 18)
                   ELSE st_length(geography(ST_Transform(the_geom, 4326))) / (maxspeed_backward * 5 / 18)
          reverse_cost_s = CASE 
               WHEN one_way = 1 THEN -st_length(geography(ST_Transform(the_geom, 4326))) / (maxspeed_backward * 5 / 18)
               ELSE st_length(geography(ST_Transform(the_geom, 4326))) / (maxspeed_backward * 5 / 18)
    WHERE rule='residential' AND class_id NOT IN (101,102,103,104,105);

    Using formulas accordingly with this part of the source code and this related issue

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.