diff --git a/README.md b/README.md index 4f6f9d3..cecb125 100644 --- a/README.md +++ b/README.md @@ -1,9 +1,3 @@ -Forked from https://github.com/abrensch/brouter - -- changed processUnused to true for safety, shortest, and trekking -- added lts_score to lookups.dat - - BRouter ======= diff --git a/brouter-map-creator/src/main/java/btools/mapcreator/DatabasePseudoTagProvider.java b/brouter-map-creator/src/main/java/btools/mapcreator/DatabasePseudoTagProvider.java index d43091b..0e9ba4f 100644 --- a/brouter-map-creator/src/main/java/btools/mapcreator/DatabasePseudoTagProvider.java +++ b/brouter-map-creator/src/main/java/btools/mapcreator/DatabasePseudoTagProvider.java @@ -90,7 +90,69 @@ public class DatabasePseudoTagProvider { } } - public DatabasePseudoTagProvider(String filename) { + public DatabasePseudoTagProvider(String filename, String jdbcurl) { + if (filename != null) doFileImport(filename); + if (jdbcurl != null) doDatabaseImport(jdbcurl); + } + + private void doDatabaseImport(String jdbcurl) { + + try (Connection conn = DriverManager.getConnection(jdbcurl)) { + + System.out.println("DatabasePseudoTagProvider reading from database: " + jdbcurl); + conn.setAutoCommit(false); + + + Map, Map> mapUnifier = new HashMap<>(); + CompactLongMap> data = new CompactLongMap<>(); + + String sql_all_tags = "SELECT * from all_tags"; + try(PreparedStatement psAllTags = conn.prepareStatement(sql_all_tags)) { + + psAllTags.setFetchSize(100); + + // process the results + ResultSet rs = psAllTags.executeQuery(); + + long dbRows = 0L; + while (rs.next()) { + long osm_id = rs.getLong("losmid"); + Map row = new HashMap<>(5); + addDBTag(row, rs, "noise_class"); + addDBTag(row, rs, "river_class"); + addDBTag(row, rs, "forest_class"); + addDBTag(row, rs, "town_class"); + addDBTag(row, rs, "traffic_class"); + + // apply the instance-unifier for the row-map + Map knownRow = mapUnifier.get(row); + if (knownRow != null) { + row = knownRow; + } else { + mapUnifier.put(row, row); + } + data.put(osm_id, row); + dbRows++; + if (dbRows % 1000000L == 0L) { + System.out.println(".. from database: rows =" + dbRows); + } + } + System.out.println("freezing result map.."); + dbData = new FrozenLongMap<>(data); + System.out.println("read from database: rows =" + dbData.size() + " unique rows=" + mapUnifier.size()); + } + + } catch (SQLException g) { + System.err.format("DatabasePseudoTagProvider execute sql .. SQL State: %s\n%s\n", g.getSQLState(), g.getMessage()); + System.exit(1); + } catch (Exception f) { + f.printStackTrace(); + System.exit(1); + } + + } + + private void doFileImport(String filename) { try (BufferedReader br = new BufferedReader(new InputStreamReader( filename.endsWith(".gz") ? new GZIPInputStream(new FileInputStream(filename)) : new FileInputStream(filename)))) { @@ -158,12 +220,22 @@ public class DatabasePseudoTagProvider { return l; } - private static void addTag(Map row, String s, String name) { + private static void addTag(Map row, String s, String name) { if (!s.isEmpty()) { row.put(name, s); } } + private static void addDBTag(Map row, ResultSet rs, String name) { + String v = null; + try { + v = rs.getString(name); + } catch (Exception e) {} + if (v != null) { + row.put("estimated_" + name, v); + } + } + public void addTags(long osm_id, Map map) { if (map == null || !map.containsKey("highway")) { @@ -194,6 +266,6 @@ public class DatabasePseudoTagProvider { pseudoTagsFound.put(key, cnt + 1L); } } - - + + } diff --git a/brouter-map-creator/src/main/java/btools/mapcreator/OsmCutter.java b/brouter-map-creator/src/main/java/btools/mapcreator/OsmCutter.java index 26de826..60f58e0 100644 --- a/brouter-map-creator/src/main/java/btools/mapcreator/OsmCutter.java +++ b/brouter-map-creator/src/main/java/btools/mapcreator/OsmCutter.java @@ -113,7 +113,11 @@ public class OsmCutter extends MapCreatorBase { } public void setDbTagFilename(String filename) { - dbPseudoTagProvider = new DatabasePseudoTagProvider(filename); + dbPseudoTagProvider = new DatabasePseudoTagProvider(filename, null); + } + + public void setDbTagDatabase(String jdbcurl) { + dbPseudoTagProvider = new DatabasePseudoTagProvider(null, jdbcurl); } @Override diff --git a/brouter-map-creator/src/main/java/btools/mapcreator/OsmFastCutter.java b/brouter-map-creator/src/main/java/btools/mapcreator/OsmFastCutter.java index cf843ca..fe67ee3 100644 --- a/brouter-map-creator/src/main/java/btools/mapcreator/OsmFastCutter.java +++ b/brouter-map-creator/src/main/java/btools/mapcreator/OsmFastCutter.java @@ -13,7 +13,7 @@ public class OsmFastCutter extends MapCreatorBase { public static void main(String[] args) throws Exception { System.out.println("*** OsmFastCutter: cut an osm map in node-tiles + way-tiles"); if (args.length != 11 && args.length != 12 && args.length != 13) { - String common = "java OsmFastCutter [db-tag-filename]"; + String common = "java OsmFastCutter [db-tag-filename | db-tag-jdbcurl]"; System.out.println("usage: bzip2 -dc | " + common); System.out.println("or : " + common + " "); @@ -37,10 +37,16 @@ public class OsmFastCutter extends MapCreatorBase { ); } - public static void doCut(File lookupFile, File nodeDir, File wayDir, File node55Dir, File way55Dir, File borderFile, File relFile, File resFile, File profileAll, File profileReport, File profileCheck, File mapFile, String dbTagFilename) throws Exception { + public static void doCut(File lookupFile, File nodeDir, File wayDir, File node55Dir, File way55Dir, File borderFile, File relFile, File resFile, File profileAll, File profileReport, File profileCheck, File mapFile, String dbTagInfo) throws Exception { // **** run OsmCutter **** OsmCutter cutter = new OsmCutter(); - if (dbTagFilename != null) cutter.setDbTagFilename(dbTagFilename); + if (dbTagInfo != null) { + if (dbTagInfo.toLowerCase().startsWith("jdbc")) { + cutter.setDbTagDatabase(dbTagInfo); + } else { + cutter.setDbTagFilename(dbTagInfo); + } + } // ... inject WayCutter cutter.wayCutter = new WayCutter(); diff --git a/brouter-util/src/main/java/btools/util/StackSampler.java b/brouter-util/src/main/java/btools/util/StackSampler.java index 53c5db6..ed35b81 100644 --- a/brouter-util/src/main/java/btools/util/StackSampler.java +++ b/brouter-util/src/main/java/btools/util/StackSampler.java @@ -47,6 +47,7 @@ public class StackSampler extends Thread { } } + @SuppressWarnings({"deprecation", "RedundantSuppression"}) // Android public void dumpThreads() { try { int wait1 = rand.nextInt(interval); diff --git a/build.gradle b/build.gradle index 6fd211e..3a04e6c 100644 --- a/build.gradle +++ b/build.gradle @@ -6,7 +6,7 @@ buildscript { google() } dependencies { - classpath 'com.android.tools.build:gradle:8.10.1' + classpath 'com.android.tools.build:gradle:8.11.1' // NOTE: Do not place your application dependencies here; they belong // in the individual module build.gradle files diff --git a/buildSrc/src/main/groovy/brouter.library-conventions.gradle b/buildSrc/src/main/groovy/brouter.library-conventions.gradle index 3fd5d46..3c48b70 100644 --- a/buildSrc/src/main/groovy/brouter.library-conventions.gradle +++ b/buildSrc/src/main/groovy/brouter.library-conventions.gradle @@ -16,6 +16,8 @@ publishing { } } publications { - gpr(MavenPublication) + gpr(MavenPublication) { + from components.java + } } } diff --git a/misc/profiles2/.gitignore b/misc/profiles2/.gitignore index 751a83b..8e365df 100644 --- a/misc/profiles2/.gitignore +++ b/misc/profiles2/.gitignore @@ -2,7 +2,7 @@ /car-fast.brf /fastbike-asia-pacific.brf /fastbike-lowtraffic.brf -#/safety.brf +/safety.brf /trekking-ignore-cr.brf /trekking-noferries.brf /trekking-nosteps.brf diff --git a/misc/profiles2/lookups.dat b/misc/profiles2/lookups.dat index d51f455..e8dafc1 100644 --- a/misc/profiles2/lookups.dat +++ b/misc/profiles2/lookups.dat @@ -711,11 +711,6 @@ estimated_town_class;0000000001 4 estimated_town_class;0000000001 5 estimated_town_class;0000000001 6 -lts_score;2000000001 1 -lts_score;2000000002 2 -lts_score;2000000003 3 -lts_score;2000000004 4 - ---context:node diff --git a/misc/profiles2/safety.brf b/misc/profiles2/safety.brf deleted file mode 100644 index 8a6345d..0000000 --- a/misc/profiles2/safety.brf +++ /dev/null @@ -1,403 +0,0 @@ -# *** The trekking profile is for slow travel -# *** and avoiding car traffic, but still with -# *** a focus on approaching your destination -# *** efficiently. - ----context:global # following code refers to global config - -# Bike profile -assign validForBikes = true - -# Use the following switches to change behaviour -assign allow_steps = true # %allow_steps% | Set false to disallow steps | boolean -assign allow_ferries = true # %allow_ferries% | Set false to disallow ferries | boolean -assign ignore_cycleroutes = false # %ignore_cycleroutes% | Set true for better elevation results | boolean -assign stick_to_cycleroutes = false # %stick_to_cycleroutes% | Set true to just follow cycleroutes | boolean -assign avoid_unsafe = true # %avoid_unsafe% | Set true to avoid standard highways | boolean - -assign add_beeline = false # %add_beeline% | Enable beeline on distant start/end points | boolean - -assign consider_noise = false # %consider_noise% | Activate to prefer a low-noise route | boolean -assign consider_river = false # %consider_river% | Activate to prefer a route along rivers, lakes, etc. | boolean -assign consider_forest = false # %consider_forest% | Activate to prefer a route in forest or parks | boolean -assign consider_town = false # %consider_town% | Activate to bypass cities / big towns as far as possible | boolean -assign consider_traffic = false # %consider_traffic% | Activate to consider traffic estimates | boolean - - - -# Change elevation parameters -assign consider_elevation = true # %consider_elevation% | Set true to favor a route with few elevation meters | boolean - -assign downhillcost = 60 # %downhillcost% | Cost for going downhill | number -assign downhillcutoff = 1.5 # %downhillcutoff% | Gradients below this value in percents are not counted. | number -assign uphillcost = 0 # %uphillcost% | Cost for going uphill | number -assign uphillcutoff = 1.5 # %uphillcutoff% | Gradients below this value in percents are not counted. | number - -assign downhillcost = if consider_elevation then downhillcost else 0 -assign uphillcost = if consider_elevation then uphillcost else 0 - -# Kinematic model parameters (travel time computation) -assign totalMass = 90 # %totalMass% | Mass (in kg) of the bike + biker, for travel time computation | number -assign maxSpeed = 45 # %maxSpeed% | Absolute maximum speed (in km/h), for travel time computation | number -assign S_C_x = 0.225 # %S_C_x% | Drag coefficient times the reference area (in m^2), for travel time computation | number -assign C_r = 0.01 # %C_r% | Rolling resistance coefficient (dimensionless), for travel time computation | number -assign bikerPower = 100 # %bikerPower% | Average power (in W) provided by the biker, for travel time computation | number - -# Turn instructions settings -assign turnInstructionMode = 1 # %turnInstructionMode% | Mode for the generated turn instructions | [0=none, 1=auto-choose, 2=locus-style, 3=osmand-style, 4=comment-style, 5=gpsies-style, 6=orux-style, 7=locus-old-style] -assign turnInstructionCatchingRange = 40 # %turnInstructionCatchingRange% | Within this distance (in m) several turning instructions are combined into one and the turning angles are better approximated to the general direction | number -assign turnInstructionRoundabouts = true # %turnInstructionRoundabouts% | Set "false" to avoid generating special turning instructions for roundabouts | boolean -assign considerTurnRestrictions = true # %considerTurnRestrictions% | Set true to take turn restrictions into account | boolean - -assign processUnusedTags = true # %processUnusedTags% | Set true to output unused tags in data tab | boolean - ----context:way # following code refers to way-tags - -# classifier constants -assign classifier_none = 1 -assign classifier_ferry = 2 - -# -# pre-calculate some logical expressions -# - -assign any_cycleroute = - if route_bicycle_icn=yes then true - else if route_bicycle_ncn=yes then true - else if route_bicycle_rcn=yes then true - else if route_bicycle_lcn=yes then true - else false - -assign nodeaccessgranted = - if any_cycleroute then true - else lcn=yes - -assign is_ldcr = - if ignore_cycleroutes then false - else any_cycleroute - -assign isbike = or bicycle_road=yes or bicycle=yes or or bicycle=permissive bicycle=designated lcn=yes -assign ispaved = surface=paved|asphalt|concrete|paving_stones|sett -assign isunpaved = not or surface= or ispaved surface=fine_gravel|cobblestone -assign probablyGood = or ispaved and ( or isbike highway=footway ) not isunpaved - - -# -# this is the cost (in Meter) for a 90-degree turn -# The actual cost is calculated as turncost*cos(angle) -# (Suppressing turncost while following longdistance-cycleways -# makes them a little bit more magnetic) -# -assign turncost = if is_ldcr then 0 - else if junction=roundabout then 0 - else 90 - - -# -# for any change in initialclassifier, initialcost is added once -# -assign initialclassifier = - if route=ferry then classifier_ferry - else classifier_none - - -# -# calculate the initial cost -# this is added to the total cost each time the costfactor -# changed -# -assign initialcost = - if ( equal initialclassifier classifier_ferry ) then 10000 - else 0 - -# -# implicit access here just from the motorroad tag -# (implicit access rules from highway tag handled elsewhere) -# -assign defaultaccess = - if access= then not motorroad=yes - else if access=private|no then false - else true - -# -# calculate logical bike access -# -assign bikeaccess = - if bicycle= then - ( - if bicycle_road=yes then true - else if vehicle= then ( if highway=footway then false else defaultaccess ) - else not vehicle=private|no - ) - else not bicycle=private|no|dismount|use_sidepath - -# -# calculate logical foot access -# -assign footaccess = - if bicycle=dismount then true - else if foot= then defaultaccess - else not foot=private|no|use_sidepath - -# -# if not bike-, but foot-acess, just a moderate penalty, -# otherwise access is forbidden -# -assign accesspenalty = - if bikeaccess then 0 - else if footaccess then 4 - else if any_cycleroute then 15 - else 10000 - -# -# handle one-ways. On primary roads, wrong-oneways should -# be close to forbidden, while on other ways we just add -# 4 to the costfactor (making it at least 5 - you are allowed -# to push your bike) -# -assign badoneway = - if reversedirection=yes then - if oneway:bicycle=yes then true - else if oneway= then junction=roundabout - else oneway=yes|true|1 - else oneway=-1 - -assign onewaypenalty = - if ( badoneway ) then - ( - if ( cycleway=opposite|opposite_lane|opposite_track ) then 0 - else if ( cycleway:left=opposite|opposite_lane|opposite_track ) then 0 - else if ( cycleway:right=opposite|opposite_lane|opposite_track ) then 0 - else if ( oneway:bicycle=no ) then 0 - else if ( cycleway:left:oneway=no ) then 0 - else if ( cycleway:right:oneway=no ) then 0 - else if ( not footaccess ) then 100 - else if ( junction=roundabout|circular ) then 60 - else if ( highway=primary|primary_link ) then 50 - else if ( highway=secondary|secondary_link ) then 30 - else if ( highway=tertiary|tertiary_link ) then 20 - else 4.0 - ) - else 0.0 - -# add estimate tags -assign traffic_penalty - switch consider_traffic - switch estimated_traffic_class= 0 - switch estimated_traffic_class=1|2 0.2 - switch estimated_traffic_class=3 0.4 - switch estimated_traffic_class=4 0.6 - switch estimated_traffic_class=5 0.8 - switch estimated_traffic_class=6|7 1 99 0 - - -assign noise_penalty - switch consider_noise - switch estimated_noise_class= 0 - switch estimated_noise_class=1 0.3 - switch estimated_noise_class=2 0.5 - switch estimated_noise_class=3 0.8 - switch estimated_noise_class=4 1.4 - switch estimated_noise_class=5 1.7 - switch estimated_noise_class=6 2 0 0 - -assign no_river_penalty - switch consider_river - switch estimated_river_class= 2 - switch estimated_river_class=1 1.3 - switch estimated_river_class=2 1 - switch estimated_river_class=3 0.7 - switch estimated_river_class=4 0.4 - switch estimated_river_class=5 0.1 - switch estimated_river_class=6 0 99 0 - -assign no_forest_penalty - switch consider_forest - switch estimated_forest_class= 1 - switch estimated_forest_class=1 0.5 - switch estimated_forest_class=2 0.4 - switch estimated_forest_class=3 0.25 - switch estimated_forest_class=4 0.15 - switch estimated_forest_class=5 0.1 - switch estimated_forest_class=6 0 99 0 - -assign town_penalty - switch consider_town - switch estimated_town_class= 0 - switch estimated_town_class=1 0.5 - switch estimated_town_class=2 0.9 - switch estimated_town_class=3 1.2 - switch estimated_town_class=4 1.3 - switch estimated_town_class=5 1.4 - switch estimated_town_class=6 1.6 99 0 - -# -# calculate the cost-factor, which is the factor -# by which the distance of a way-segment is multiplied -# to calculate the cost of that segment. The costfactor -# must be >=1 and it's supposed to be close to 1 for -# the type of way the routing profile is searching for -# -assign isresidentialorliving = or highway=residential|living_street living_street=yes -assign costfactor - - # - # exclude rivers, rails etc. - # - if ( and highway= not route=ferry ) then 10000 - - # - # exclude motorways and proposed roads - # - else if ( highway=motorway|motorway_link ) then 10000 - else if ( highway=proposed|abandoned ) then 10000 - - # - # all other exclusions below (access, steps, ferries,..) - # should not be deleted by the decoder, to be available - # in voice-hint-processing - # - else min 9999 - - add town_penalty - add no_forest_penalty - add no_river_penalty - add noise_penalty - add traffic_penalty - - # - # apply oneway-and access-penalties - # - add max onewaypenalty accesspenalty - - # - # steps and ferries are special. Note this is handled - # before the cycleroute-switch, to be able - # to really exclude them be setting cost to infinity - # - if ( highway=steps ) then ( if allow_steps then 40 else 10000 ) - else if ( route=ferry ) then ( if allow_ferries then 5.67 else 10000 ) - - # - # handle long-distance cycle-routes. - # - else if ( is_ldcr ) then 1 # always treated as perfect (=1) - else - add ( if stick_to_cycleroutes then 0.5 else 0.05 ) # everything else somewhat up - - # - # some other highway types - # - if ( highway=pedestrian ) then 3 - else if ( highway=bridleway ) then 5 - else if ( highway=cycleway ) then 1 - else if ( isresidentialorliving ) then ( if isunpaved then 1.5 else 1.1 ) - else if ( highway=service ) then ( if isunpaved then 1.6 else 1.3 ) - - # - # tracks and track-like ways are rated mainly be tracktype/grade - # But note that if no tracktype is given (mainly for road/path/footway) - # it can be o.k. if there's any other hint for quality - # - else if ( highway=track|road|path|footway ) then - ( - if ( tracktype=grade1 ) then ( if probablyGood then 1.0 else 1.3 ) - else if ( tracktype=grade2 ) then ( if probablyGood then 1.1 else 2.0 ) - else if ( tracktype=grade3 ) then ( if probablyGood then 1.5 else 3.0 ) - else if ( tracktype=grade4 ) then ( if probablyGood then 2.0 else 5.0 ) - else if ( tracktype=grade5 ) then ( if probablyGood then 3.0 else 5.0 ) - else ( if probablyGood then 1.0 else 5.0 ) - ) - - # - # When avoiding unsafe ways, avoid highways without a bike hint - # - else add ( if ( and avoid_unsafe not isbike ) then 2 else 0 ) - - # - # actuals roads are o.k. if we have a bike hint - # - if ( highway=trunk|trunk_link ) then ( if isbike then 1.5 else 10 ) - else if ( highway=primary|primary_link ) then ( if isbike then 1.2 else 3 ) - else if ( highway=secondary|secondary_link ) then ( if isbike then 1.1 else 1.6 ) - else if ( highway=tertiary|tertiary_link ) then ( if isbike then 1.0 else 1.4 ) - else if ( highway=unclassified ) then ( if isbike then 1.0 else 1.3 ) - - # - # default for any other highway type not handled above - # - else 2.0 - - -# way priorities used for voice hint generation - -assign priorityclassifier = - - if ( highway=motorway ) then 30 - else if ( highway=motorway_link ) then 29 - else if ( highway=trunk ) then 28 - else if ( highway=trunk_link ) then 27 - else if ( highway=primary ) then 26 - else if ( highway=primary_link ) then 25 - else if ( highway=secondary ) then 24 - else if ( highway=secondary_link ) then 23 - else if ( highway=tertiary ) then 22 - else if ( highway=tertiary_link ) then 21 - else if ( highway=unclassified ) then 20 - else if ( isresidentialorliving ) then 6 - else if ( highway=service ) then 6 - else if ( highway=cycleway ) then 6 - else if ( or bicycle=designated bicycle_road=yes ) then 6 - else if ( highway=track ) then if tracktype=grade1 then 6 else 4 - else if ( highway=bridleway|road|path|footway ) then 4 - else if ( highway=steps ) then 2 - else if ( highway=pedestrian ) then 2 - else 0 - -# some more classifying bits used for voice hint generation... - -assign isbadoneway = not equal onewaypenalty 0 -assign isgoodoneway = if reversedirection=yes then oneway=-1 - else if oneway= then junction=roundabout else oneway=yes|true|1 -assign isroundabout = junction=roundabout -assign islinktype = highway=motorway_link|trunk_link|primary_link|secondary_link|tertiary_link -assign isgoodforcars = if greater priorityclassifier 6 then true - else if ( or isresidentialorliving highway=service ) then true - else if ( and highway=track tracktype=grade1 ) then true - else false - -# ... encoded into a bitmask - -assign classifiermask add isbadoneway - add multiply isgoodoneway 2 - add multiply isroundabout 4 - add multiply islinktype 8 - multiply isgoodforcars 16 - -# include `smoothness=` tags in the response's WayTags for track analysis -assign dummyUsage = smoothness= - ----context:node # following code refers to node tags - -assign defaultaccess = - if ( access= ) then true # add default barrier restrictions here! - else if ( access=private|no ) then false - else true - -assign bikeaccess = - if nodeaccessgranted=yes then true - else if bicycle= then - ( - if vehicle= then defaultaccess - else not vehicle=private|no - ) - else not bicycle=private|no|dismount - -assign footaccess = - if bicycle=dismount then true - else if foot= then defaultaccess - else not foot=private|no - -assign initialcost = - if bikeaccess then 0 - else ( if footaccess then 100 else 1000000 ) diff --git a/misc/profiles2/shortest.brf b/misc/profiles2/shortest.brf index cd1034e..f4e66db 100644 --- a/misc/profiles2/shortest.brf +++ b/misc/profiles2/shortest.brf @@ -12,9 +12,6 @@ assign validForFoot 1 ---context:way # following code refers to way-tags -# show unused tags -assign processUnusedTags = true - assign any_cycleroute or route_bicycle_icn=yes or route_bicycle_ncn=yes or route_bicycle_rcn=yes route_bicycle_lcn=yes assign nodeaccessgranted or any_cycleroute lcn=yes diff --git a/misc/profiles2/trekking.brf b/misc/profiles2/trekking.brf index 231a939..570a883 100644 --- a/misc/profiles2/trekking.brf +++ b/misc/profiles2/trekking.brf @@ -49,7 +49,7 @@ assign turnInstructionCatchingRange = 40 # %turnInstructionCatchingRange% | W assign turnInstructionRoundabouts = true # %turnInstructionRoundabouts% | Set "false" to avoid generating special turning instructions for roundabouts | boolean assign considerTurnRestrictions = true # %considerTurnRestrictions% | Set true to take turn restrictions into account | boolean -assign processUnusedTags = true # %processUnusedTags% | Set true to output unused tags in data tab | boolean +assign processUnusedTags = false # %processUnusedTags% | Set true to output unused tags in data tab | boolean ---context:way # following code refers to way-tags @@ -247,10 +247,10 @@ assign costfactor if ( and highway= not route=ferry ) then 10000 # - # exclude motorways and proposed roads + # exclude motorways and proposed, abandoned under construction roads # - else if ( highway=motorway|motorway_link ) then 10000 - else if ( highway=proposed|abandoned ) then 10000 + else if ( highway=motorway|motorway_link ) then 10000 + else if ( highway=proposed|abandoned|construction ) then 10000 # # all other exclusions below (access, steps, ferries,..)