variable length tag descriptions (first shot)

This commit is contained in:
Arndt 2014-05-18 19:17:05 +02:00
parent 6768a197ba
commit a145230e0f
23 changed files with 860 additions and 124 deletions

View file

@ -40,15 +40,18 @@ public final class BExpressionContext
private int[] lookupData = new int[0];
private byte[] abBuf = new byte[256];
private Map<String,Integer> variableNumbers = new HashMap<String,Integer>();
private float[] variableData;
// hash-cache for function results
private long[] _arrayBitmap;
private byte[][] _arrayBitmap;
private int currentHashBucket = -1;
private long currentBitmap = 0;
private byte[] currentByteArray = null;
private boolean currentInversion = false;
public List<BExpression> expressionList;
@ -85,7 +88,7 @@ public final class BExpressionContext
public BExpressionContext( String context, int hashSize )
{
this.context = context;
_arrayBitmap = new long[hashSize];
_arrayBitmap = new byte[hashSize][];
_arrayCostfactor = new float[hashSize];
_arrayTurncost = new float[hashSize];
@ -94,62 +97,79 @@ public final class BExpressionContext
/**
* encode lookup data to a 64-bit word
* encode lookup data to a byte array
*/
public long encode( int[] ld )
public byte[] encode()
{
long w = 0;
for( int inum = 0; inum < lookupValues.size(); inum++ ) // loop over lookup names
return encode( lookupData );
}
public byte[] encode( int[] ld )
{
// start with first bit hardwired ("reversedirection")
int idx = 0;
int bm = 2; // byte mask
abBuf[0] = (byte)(ld[0] == 0 ? 0 : 1);
// all others are generic
for( int inum = 1; inum < lookupValues.size(); inum++ ) // loop over lookup names
{
int n = lookupValues.get(inum).length - 1;
int d = ld[inum];
int im = 1; // integer mask
if ( n == 2 ) { n = 1; d = d == 2 ? 1 : 0; } // 1-bit encoding for booleans
while( n != 0 ) { n >>= 1; w <<= 1; }
w |= (long)d;
while( n != 0 )
{
if ( bm == 0x100 ) { bm = 1; abBuf[++idx] = 0; }
if ( (d & im) != 0 ) abBuf[idx] |= bm;
n >>= 1;
bm <<= 1;
im <<= 1;
}
}
return w;
idx++;
byte[] ab = new byte[idx];
System.arraycopy( abBuf, 0, ab, 0, idx );
return ab;
}
/**
* decode a 64-bit word into a lookup data array
* decode a byte-array into a lookup data array
*/
public void decode( int[] ld, long w )
public void decode( int[] ld, byte[] ab )
{
for( int inum = lookupValues.size()-1; inum >= 0; inum-- ) // loop over lookup names
// start with first bit hardwired ("reversedirection")
int idx = 1;
int bm = 2; // byte mask
int b = ab[0];
ld[0] = (b & 1) == 0 ? 0 : 2;
// all others are generic
for( int inum = 1; inum < lookupValues.size(); inum++ ) // loop over lookup names
{
int nv = lookupValues.get(inum).length;
int n = nv == 3 ? 1 : nv-1; // 1-bit encoding for booleans
int m = 0;
long ww = w;
while( n != 0 ) { n >>= 1; ww >>= 1; m = m<<1 | 1; }
int d = (int)(w & m);
int d = 0;
int im = 1; // integer mask
while( n != 0 )
{
if ( bm == 0x100 ) { bm = 1; b = ab[idx++]; }
if ( (b & bm) != 0 ) d |= im;
n >>= 1;
bm <<= 1;
im <<= 1;
}
if ( nv == 3 && d == 1 ) d = 2; // 1-bit encoding for booleans
ld[inum] = d;
w = ww;
}
}
/**
* much like decode, but just for counting bits
*/
private void countBits()
{
int bits = 0;
for( int inum = lookupValues.size()-1; inum >= 0; inum-- ) // loop over lookup names
{
int nv = lookupValues.get(inum).length;
int n = nv == 3 ? 1 : nv-1; // 1-bit encoding for booleans
while( n != 0 ) { n >>= 1; bits++; }
}
// System.out.println( "context=" + context + ",bits=" + bits + " keys=" + lookupValues.size() );
if ( bits > 64 ) throw new IllegalArgumentException( "lookup table for context " + context + " exceeds 64 bits!" );
}
public String getCsvDescription( long bitmap )
public String getCsvDescription( byte[] ab )
{
StringBuilder sb = new StringBuilder( 200 );
decode( lookupData, bitmap );
decode( lookupData, ab );
for( int inum = 0; inum < lookupValues.size(); inum++ ) // loop over lookup names
{
BExpressionLookupValue[] va = lookupValues.get(inum);
@ -168,10 +188,10 @@ public final class BExpressionContext
return sb.toString();
}
public String getKeyValueDescription( long bitmap )
public String getKeyValueDescription( byte[] ab )
{
StringBuilder sb = new StringBuilder( 200 );
decode( lookupData, bitmap );
decode( lookupData, ab );
for( int inum = 0; inum < lookupValues.size(); inum++ ) // loop over lookup names
{
BExpressionLookupValue[] va = lookupValues.get(inum);
@ -192,6 +212,7 @@ public final class BExpressionContext
int parsedLines = 0;
boolean ourContext = false;
addLookupValue( "reversedirection", "yes", null );
for(;;)
{
String line = br.readLine();
@ -215,6 +236,7 @@ public final class BExpressionContext
String value = tk.nextToken();
int idx = name.indexOf( ';' );
if ( idx >= 0 ) name = name.substring( 0, idx );
if ( "reversedirection".equals( name ) ) continue; // this is hardcoded
BExpressionLookupValue newValue = addLookupValue( name, value, null );
// add aliases
@ -229,7 +251,6 @@ public final class BExpressionContext
// post-process metadata:
lookupDataFrozen = true;
countBits();
}
catch( Exception e )
{
@ -237,7 +258,7 @@ public final class BExpressionContext
}
}
private void evaluate( int[] lookupData2 )
public void evaluate( int[] lookupData2 )
{
lookupData = lookupData2;
for( BExpression exp: expressionList)
@ -248,27 +269,55 @@ public final class BExpressionContext
public void evaluate( long bitmap, BExpressionReceiver receiver )
public void evaluate( boolean inverseDirection, byte[] ab, BExpressionReceiver receiver )
{
_receiver = receiver;
if ( currentBitmap != bitmap || currentHashBucket < 0 )
int abLen = ab.length;
boolean equalsCurrent = currentHashBucket >= 0 && abLen == currentByteArray.length;
if ( equalsCurrent )
{
// calc hash bucket from crc
int crc = Crc32.crc( bitmap );
int hashSize = _arrayBitmap.length;
currentHashBucket = (crc & 0xfffffff) % hashSize;
currentBitmap = bitmap;
if ( (inverseDirection ? ab[0] ^ 1 : ab[0] ) == currentByteArray[0] )
{
for( int i=1; i<abLen; i++ )
{
if ( ab[i] != currentByteArray[i] ) { equalsCurrent = false; break; }
}
}
else equalsCurrent = false;
}
if ( _arrayBitmap[currentHashBucket] == bitmap )
if ( equalsCurrent )
{
return;
}
else
{
// calc hash bucket from crc
int crc = Crc32.crc( abBuf, 0, abLen );
int hashSize = _arrayBitmap.length;
currentHashBucket = (crc & 0xfffffff) % hashSize;
currentByteArray = new byte[abLen];
System.arraycopy( ab, 0, currentByteArray, 0 , abLen );
if ( inverseDirection ) currentByteArray[0] ^= 1;
}
_arrayBitmap[currentHashBucket] = bitmap;
boolean hashBucketEquals = false;
byte[] abBucket = _arrayBitmap[currentHashBucket];
if ( abBucket != null && abBucket.length == abLen )
{
hashBucketEquals = true;
for( int i=0; i<abLen; i++ )
{
if ( abBucket[i] != currentByteArray[i] ) { hashBucketEquals = false; break; }
}
}
if ( hashBucketEquals ) return;
_arrayBitmap[currentHashBucket] = currentByteArray;
decode( lookupData, bitmap );
decode( lookupData, ab );
evaluate( lookupData );
_arrayCostfactor[currentHashBucket] = variableData[costfactorIdx];
@ -412,6 +461,25 @@ public final class BExpressionContext
return newValue;
}
/**
* add a value-index to to internal array
* value-index means 0=unknown, 1=other, 2=value-x, ...
*/
public void addLookupValue( String name, int valueIndex )
{
Integer num = lookupNumbers.get( name );
if ( num == null )
{
return;
}
// look for that value
int inum = num.intValue();
int nvalues = lookupValues.get( inum ).length;
if ( valueIndex < 0 || valueIndex >= nvalues ) throw new IllegalArgumentException( "value index out of range for name " + name + ": " + valueIndex );
lookupData[inum] = valueIndex;
}
public void parseFile( File file, String readOnlyContext )
{
try
@ -423,7 +491,7 @@ public final class BExpressionContext
context = readOnlyContext;
expressionList = _parseFile( file );
variableData = new float[variableNumbers.size()];
evaluate( 1L, null );
evaluate( lookupData ); // lookupData is dummy here - evaluate just to create the variables
context = realContext;
}
linenr = 1;
@ -592,7 +660,7 @@ public final class BExpressionContext
public void expressionWarning( String message )
{
_arrayBitmap[currentHashBucket] = 0L; // no caching if warnings
_arrayBitmap[currentHashBucket] = null; // no caching if warnings
if ( _receiver != null ) _receiver.expressionWarning( context, message );
}
}

View file

@ -0,0 +1,46 @@
package btools.expressions;
import java.util.*;
import java.io.*;
import java.net.URL;
import org.junit.Assert;
import org.junit.Test;
public class EncodeDecodeTest
{
@Test
public void encodeDecodeTest()
{
URL lookupurl = this.getClass().getResource( "/lookups.dat" );
Assert.assertTrue( "lookup file lookup.dat not found", lookupurl != null );
File lookupFile = new File(lookupurl.getFile());
File workingDir = lookupFile.getParentFile();
// read lookup.dat + trekking.brf
BExpressionContext expctxWay = new BExpressionContext("way");
expctxWay.readMetaData( lookupFile );
expctxWay.parseFile( new File( workingDir, "trekking.brf" ), "global" );
String[] tags = { "highway=residential", "oneway=yes", "reversedirection=yes" };
// encode the tags into 64 bit description word
int[] lookupData = expctxWay.createNewLookupData();
for( String arg: tags )
{
int idx = arg.indexOf( '=' );
if ( idx < 0 ) throw new IllegalArgumentException( "bad argument (should be <tag>=<value>): " + arg );
String key = arg.substring( 0, idx );
String value = arg.substring( idx+1 );
expctxWay.addLookupValue( key, value, lookupData );
}
byte[] description = expctxWay.encode(lookupData);
// calculate the cost factor from that description
expctxWay.evaluate( false, description, null );
float costfactor = expctxWay.getCostfactor();
Assert.assertTrue( "costfactor mismatch", Math.abs( costfactor - 5.1 ) > 0.00001 );
}
}

View file

@ -0,0 +1,317 @@
---lookupversion:2
---context:way
highway;0001731794 track
highway;0001457935 residential
highway;0000968516 service
highway;0000756237 footway
highway;0000521566 path
highway;0000261772 unclassified
highway;0000220315 secondary
highway;0000207585 tertiary
highway;0000103445 steps
highway;0000102114 primary
highway;0000094484 cycleway
highway;0000090388 living_street
highway;0000035041 motorway
highway;0000029965 pedestrian
highway;0000026875 motorway_link
highway;0000015054 trunk
highway;0000014604 primary_link
highway;0000012211 road
highway;0000011822 trunk_link
highway;0000005882 construction
highway;0000005425 bridleway
highway;0000005180 secondary_link
highway;0000003360 platform
highway;0000002616 proposed abandoned
highway;0000001374 tertiary_link
highway;0000000760 ferry
highway;0000000541 raceway
highway;0000000346 rest_area
highway;0000000300 bus_stop
highway;0000000184 services
tracktype;0000356503 grade2
tracktype;0000353482 grade3
tracktype;0000281625 grade1
tracktype;0000245193 grade4
tracktype;0000179135 grade5
surface;0000363915 asphalt
surface;0000303589 paved
surface;0000196783 gravel
surface;0000137371 ground
surface;0000128215 grass
surface;0000092748 unpaved
surface;0000086579 paving_stones
surface;0000066111 cobblestone
surface;0000042061 dirt
surface;0000026551 concrete
surface;0000025631 compacted
surface;0000019861 sand
surface;0000009400 pebblestone
surface;0000003197 fine_gravel
maxspeed;0000402224 30
maxspeed;0000224685 50
maxspeed;0000045177 100
maxspeed;0000037529 70
maxspeed;0000014237 none
maxspeed;0000014022 60
maxspeed;0000011530 80
maxspeed;0000009951 10
maxspeed;0000008056 20
maxspeed;0000005772 120
maxspeed;0000003165 40
maxspeed;0000002987 7
maxspeed;0000002826 signals
maxspeed;0000001933 130
service;0000221481 parking_aisle
service;0000157110 driveway
lit;0000132495 yes
lanes;0000098207 2
lanes;0000042192 1
lanes;0000018533 3
lanes;0000004577 4
lanes;0000000448 5
lanes;0000000318 1.5
access;0000044859 yes permissive
access;0000008452 designated official
access;0000028727 destination customers
access;0000076985 agricultural forestry
access;0000116270 private
access;0000028044 no
foot;0000339384 yes allowed Yes
foot;0000125339 designated official
foot;0000018945 no
foot;0000001562 private
foot;0000000279 destination
foot;0000008172 permissive
bicycle;0000302789 yes allowed permissive
bicycle;0000108056 designated official
bicycle;0000000265 destination
bicycle;0000003593 dismount
bicycle;0000001426 private
bicycle;0000070179 no
motorcar;0000010111 yes permissive
motorcar;0000001537 designated official
motorcar;0000007102 destination
motorcar;0000016706 agricultural forestry agriculture
motorcar;0000002178 private
motorcar;0000077771 no
motor_vehicle;0000013813 yes permissive
motor_vehicle;0000002098 designated official
motor_vehicle;0000009792 destination
motor_vehicle;0000019301 agricultural forestry
motor_vehicle;0000006563 private
motor_vehicle;0000025491 no
motorcycle;0000005750 yes permissive
motorcycle;0000001158 designated official
motorcycle;0000005805 destination
motorcycle;0000012401 agricultural forestry
motorcycle;0000001180 private
motorcycle;0000053955 no
vehicle;0000000505 yes permissive
vehicle;0000000027 designated
vehicle;0000007582 destination
vehicle;0000004357 agricultural forestry
vehicle;0000001155 private
vehicle;0000006487 no
cycleway;0000033575 track
cycleway;0000012829 no
cycleway;0000011604 lane
cycleway;0000008938 opposite
cycleway;0000001503 none
cycleway;0000001146 right
cycleway;0000001031 opposite_track
cycleway;0000001029 yes
cycleway;0000000856 opposite_lane
cycleway;0000000675 both
cycleway;0000000665 left
cycleway;0000000521 shared
cycleway;0000000383 street
cycleway;0000000176 segregated
mtb:scale;0000043968 0
mtb:scale;0000019705 1
mtb:scale;0000006436 2
mtb:scale;0000002702 3
mtb:scale;0000001083 4
mtb:scale;0000000329 5
sac_scale;0000049626 hiking
sac_scale;0000007933 mountain_hiking
sac_scale;0000001160 demanding_mountain_hiking
sac_scale;0000000523 yes
sac_scale;0000000364 alpine_hiking
sac_scale;0000000117 demanding_alpine_hiking
noexit;0000058492 yes
motorroad;0000019250 yes
oneway;0000330245 yes
oneway;0000075148 no
oneway;0000003679 -1
oneway;0000000001 true
oneway;0000000001 1
junction;0000015929 roundabout
bridge;0000182649 yes viaduct true suspension
tunnel;0000031626 yes
lcn;0000018999 yes
longdistancecycleway;0000000001 yes
reversedirection;0000000001 yes
---context:node
highway;0000100947 turning_circle
highway;0000067645 traffic_signals
highway;0000047209 crossing
highway;0000037164 bus_stop
highway;0000006577 motorway_junction
highway;0000003811 stop
highway;0000002331 mini_roundabout
highway;0000001789 milestone
highway;0000001692 passing_place
highway;0000001289 give_way
highway;0000001092 emergency_access_point
highway;0000000683 speed_camera
highway;0000000672 steps
highway;0000000658 incline_steep
highway;0000000620 elevator
highway;0000000506 street_lamp
highway;0000000490 ford
highway;0000000458 incline
highway;0000000135 rest_area
highway;0000000105 path
highway;0000000098 emergency_bay
highway;0000000096 road
highway;0000000087 platform
highway;0000000074 services
highway;0000000058 track
highway;0000000055 service
highway;0000000054 footway
highway;0000000053 traffic_calming
highway;0000000046 toll_bridge
highway;0000000037 city_entry
barrier;0000076979 gate
barrier;0000069308 bollard
barrier;0000028131 lift_gate
barrier;0000017332 cycle_barrier
barrier;0000005693 entrance
barrier;0000002885 block
barrier;0000001065 kissing_gate
barrier;0000000828 cattle_grid
barrier;0000000602 stile
barrier;0000000561 turnstile
barrier;0000000512 no
barrier;0000000463 fence
barrier;0000000417 bump_gate
barrier;0000000324 sally_port
barrier;0000000283 yes
barrier;0000000283 hampshire_gate
barrier;0000000236 swing_gate
barrier;0000000203 chain
barrier;0000000181 toll_booth
barrier;0000000180 door
barrier;0000000104 chicane
barrier;0000000096 tree
barrier;0000000087 border_control
barrier;0000000077 log
barrier;0000000076 traffic_crossing_pole
barrier;0000000063 wall
barrier;0000000060 fallen_tree
barrier;0000000052 stone
barrier;0000000048 ditch
barrier;0000000031 spikes
access;0000001309 yes permissive
access;0000000118 designated official
access;0000000405 destination customers
access;0000000276 agricultural forestry
access;0000008574 private
access;0000002145 no
foot;0000080681 yes permissive
foot;0000000326 designated official
foot;0000000023 destination
foot;0000000156 private
foot;0000009170 no
bicycle;0000076717 yes permissive
bicycle;0000000406 designated official
bicycle;0000000018 destination
bicycle;0000000081 dismount
bicycle;0000000051 private
bicycle;0000016121 no
motorcar;0000005785 yes permissive
motorcar;0000000026 designated official
motorcar;0000000080 destination
motorcar;0000000112 agricultural forestry
motorcar;0000000171 private
motorcar;0000001817 no
motor_vehicle;0000000066 yes permissive
motor_vehicle;0000000000 designated official
motor_vehicle;0000000030 destination
motor_vehicle;0000000073 agricultural forestry
motor_vehicle;0000000136 private
motor_vehicle;0000000469 no
motorcycle;0000004515 yes permissive
motorcycle;0000000007 designated official
motorcycle;0000000054 destination
motorcycle;0000000027 agricultural forestry
motorcycle;0000000063 private
motorcycle;0000001637 no
vehicle;0000000058 yes permissive
vehicle;0000000000 designated
vehicle;0000000081 destination
vehicle;0000000038 agricultural forestry
vehicle;0000000041 private
vehicle;0000000271 no
crossing;0000032485 traffic_signals
crossing;0000014300 uncontrolled
crossing;0000005086 island
crossing;0000001565 unmarked
crossing;0000001066 no
crossing;0000000333 zebra
railway;0000034039 level_crossing
railway;0000010175 crossing
noexit;0000043010 yes
entrance;0000015094 yes
entrance;0000007079 main
entrance;0000000554 service
entrance;0000000169 emergency
entrance;0000000063 exit
entrance;0000000008 private
lcn;0000018999 yes
longdistancecycleway;0000000001 yes

View file

@ -0,0 +1,225 @@
# *** 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
# Use the following switches to change behaviour
# (1=yes, 0=no):
assign consider_elevation 1 # set to 0 to ignore elevation in routing
assign allow_steps 1 # set to 0 to disallow steps
assign allow_ferries 1 # set to 0 to disallow ferries
assign ignore_cycleroutes 0 # set to 1 for better elevation results
assign stick_to_cycleroutes 0 # set to 1 to just follow cycleroutes
assign avoid_unsafe 0 # set to 1 to avoid standard highways
assign validForBikes 1
# the elevation parameters
assign downhillcost switch consider_elevation 60 0
assign downhillcutoff 1.5
assign uphillcost 0
assign uphillcutoff 1.5
---context:way # following code refers to way-tags
#
# pre-calculate some logical expressions
#
assign is_ldcr and longdistancecycleway=yes not ignore_cycleroutes
assign isbike or bicycle=yes or bicycle=designated lcn=yes
assign ispaved or surface=paved or surface=asphalt or surface=concrete surface=paving_stones
assign isunpaved not or surface= or ispaved or surface=fine_gravel surface=cobblestone
assign probablyGood or ispaved and isbike 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 switch is_ldcr 0 90
#
# calculate the initial cost
# this is added to the total cost each time the costfactor
# changed
#
assign initialcost switch highway=ferry 10000 0
#
# implicit access here just from the motorroad tag
# (implicit access rules from highway tag handled elsewhere)
#
assign defaultaccess
switch access=
not motorroad=yes
switch or access=private access=no
0
1
#
# calculate logical bike access
#
assign bikeaccess
or longdistancecycleway=yes
switch bicycle=
switch vehicle=
defaultaccess
switch or vehicle=private vehicle=no
0
1
not or bicycle=private or bicycle=no bicycle=dismount
#
# calculate logical foot access
#
assign footaccess
or bikeaccess
or bicycle=dismount
switch foot=
defaultaccess
not or foot=private foot=no
#
# if not bike-, but foot-acess, just a moderate penalty,
# otherwise access is forbidden
#
assign accesspenalty
switch bikeaccess
0
switch footaccess
4
100000
#
# 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 oneway
switch oneway=
junction=roundabout
or oneway=yes or oneway=true oneway=1
assign onewaypenalty
switch switch reversedirection=yes oneway oneway=-1
switch or cycleway=opposite or cycleway=opposite_lane cycleway=opposite_track 0
switch or highway=primary highway=primary_link 50
switch or highway=secondary highway=secondary_link 30
switch or highway=tertiary highway=tertiary_link 20
4.0
0.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 costfactor
add max onewaypenalty accesspenalty
#
# steps and ferries are special. Note this is handled
# before the longdistancecycleway-switch, to be able
# to really exlude them be setting cost to infinity
#
switch highway=steps switch allow_steps 40 100000
switch highway=ferry switch allow_ferries 5.67 100000
#
# handle long-distance cycle-routes.
#
switch is_ldcr 1 # always treated as perfect (=1)
add switch stick_to_cycleroutes 0.5 0.05 # everything else somewhat up
#
# some other highway types
#
switch highway=pedestrian 3
switch highway=bridleway 5
switch highway=cycleway 1
switch or highway=residential highway=living_street switch isunpaved 1.5 1.1
switch highway=service switch isunpaved 1.6 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
#
switch or highway=track or highway=road or highway=path highway=footway
switch tracktype=grade1 switch probablyGood 1.0 1.3
switch tracktype=grade2 switch probablyGood 1.1 2.0
switch tracktype=grade3 switch probablyGood 1.5 3.0
switch tracktype=grade4 switch probablyGood 2.0 5.0
switch tracktype=grade5 switch probablyGood 3.0 5.0
switch probablyGood 1.0 5.0
#
# When avoiding unsafe ways, avoid highways without a bike hint
#
add switch and avoid_unsafe not isbike 2 0
#
# exclude motorways and proposed roads
#
switch or highway=motorway highway=motorway_link 100000
switch highway=proposed 100000
#
# actuals roads are o.k. if we have a bike hint
#
switch or highway=trunk highway=trunk_link switch isbike 1.5 10
switch or highway=primary highway=primary_link switch isbike 1.2 3
switch or highway=secondary highway=secondary_link switch isbike 1.1 1.6
switch or highway=tertiary highway=tertiary_link switch isbike 1.0 1.4
switch highway=unclassified switch isbike 1.0 1.3
#
# default for any other highway type not handled above
#
2.0
---context:node # following code refers to node tags
assign defaultaccess
switch access=
1 # add default barrier restrictions here!
switch or access=private access=no
0
1
assign bikeaccess
or or longdistancecycleway=yes lcn=yes
switch bicycle=
switch vehicle=
defaultaccess
switch or vehicle=private vehicle=no
0
1
switch or bicycle=private or bicycle=no bicycle=dismount
0
1
assign footaccess
or bicycle=dismount
switch foot=
defaultaccess
switch or foot=private foot=no
0
1
assign initialcost
switch bikeaccess
0
switch footaccess
100
1000000