network and access checks on cycle relations

This commit is contained in:
Arndt 2014-04-21 12:26:06 +02:00
parent 2b70d8a862
commit 1b8c3ccea8
10 changed files with 409 additions and 10 deletions

View file

@ -168,6 +168,22 @@ public final class BExpressionContext
return sb.toString(); return sb.toString();
} }
public String getKeyValueDescription( long bitmap )
{
StringBuilder sb = new StringBuilder( 200 );
decode( lookupData, bitmap );
for( int inum = 0; inum < lookupValues.size(); inum++ ) // loop over lookup names
{
BExpressionLookupValue[] va = lookupValues.get(inum);
String value = va[lookupData[inum]].toString();
if ( value != null && value.length() > 0 )
{
sb.append( " " + lookupNames.get( inum ) + "=" + value );
}
}
return sb.toString();
}
public void readMetaData( File lookupsFile ) public void readMetaData( File lookupsFile )
{ {
try try

View file

@ -174,11 +174,16 @@ public class OsmCutter extends MapCreatorBase
return; return;
} }
String network = r.getTag( "network" );
if ( network == null ) network = "";
writeId( cyclewayDos, r.rid );
cyclewayDos.writeUTF( network );
for ( int i=0; i<r.ways.size();i++ ) for ( int i=0; i<r.ways.size();i++ )
{ {
long wid = r.ways.get(i); long wid = r.ways.get(i);
writeId( cyclewayDos, wid ); writeId( cyclewayDos, wid );
} }
writeId( cyclewayDos, -1 );
} }

View file

@ -0,0 +1,74 @@
package btools.mapcreator;
import java.io.DataInputStream;
import java.io.EOFException;
import java.io.File;
import java.util.HashMap;
import btools.util.DenseLongMap;
import btools.util.TinyDenseLongMap;
/**
* WayCutter does 2 step in map-processing:
*
* - cut the way file into 45*30 - pieces
* - enrich ways with relation information
*
* @author ab
*/
public class RelationStatistics extends MapCreatorBase
{
public static void main(String[] args) throws Exception
{
System.out.println("*** RelationStatistics: count relation networks");
if (args.length != 1)
{
System.out.println("usage: java WayCutter <relation-file>" );
return;
}
new RelationStatistics().process( new File( args[0] ) );
}
public void process( File relationFileIn ) throws Exception
{
HashMap<String,long[]> relstats = new HashMap<String,long[]>();
DataInputStream dis = createInStream( relationFileIn );
try
{
for(;;)
{
long rid = readId( dis );
String network = dis.readUTF();
int waycount = 0;
for(;;)
{
long wid = readId( dis );
if ( wid == -1 ) break;
waycount++;
}
long[] stat = relstats.get( network );
if ( stat == null )
{
stat = new long[2];
relstats.put( network, stat );
}
stat[0]++;
stat[1] += waycount;
}
}
catch( EOFException eof )
{
dis.close();
}
for( String network : relstats.keySet() )
{
long[] stat = relstats.get( network );
System.out.println( "network: " + network + " has " + stat[0] + " relations with " + stat[1] + " ways" );
}
}
}

View file

@ -4,8 +4,10 @@ import java.io.DataInputStream;
import java.io.EOFException; import java.io.EOFException;
import java.io.File; import java.io.File;
import btools.expressions.BExpressionContext;
import btools.util.CompactLongSet; import btools.util.CompactLongSet;
import btools.util.DenseLongMap; import btools.util.DenseLongMap;
import btools.util.FrozenLongSet;
import btools.util.TinyDenseLongMap; import btools.util.TinyDenseLongMap;
/** /**
@ -20,38 +22,58 @@ public class WayCutter extends MapCreatorBase
{ {
private CompactLongSet cyclewayset; private CompactLongSet cyclewayset;
private DenseLongMap tileIndexMap; private DenseLongMap tileIndexMap;
private BExpressionContext expctxReport;
private BExpressionContext expctxCheck;
public static void main(String[] args) throws Exception public static void main(String[] args) throws Exception
{ {
System.out.println("*** WayCutter: Soft-Cut way-data into tiles"); System.out.println("*** WayCutter: Soft-Cut way-data into tiles");
if (args.length != 4) if (args.length != 7)
{ {
System.out.println("usage: java WayCutter <node-tiles-in> <way-file-in> <way-tiles-out> <relation-file>" ); System.out.println("usage: java WayCutter <node-tiles-in> <way-file-in> <way-tiles-out> <relation-file> <lookup-file> <report-profile> <check-profile>" );
return; return;
} }
new WayCutter().process( new File( args[0] ), new File( args[1] ), new File( args[2] ), new File( args[3] ) ); new WayCutter().process( new File( args[0] ), new File( args[1] ), new File( args[2] ), new File( args[3] ), new File( args[4] ), new File( args[5] ), new File( args[6] ) );
} }
public void process( File nodeTilesIn, File wayFileIn, File wayTilesOut, File relationFileIn ) throws Exception public void process( File nodeTilesIn, File wayFileIn, File wayTilesOut, File relationFileIn, File lookupFile, File reportProfile, File checkProfile ) throws Exception
{ {
this.outTileDir = wayTilesOut; this.outTileDir = wayTilesOut;
// read lookup + profile for relation access-check
expctxReport = new BExpressionContext("way");
expctxReport.readMetaData( lookupFile );
expctxReport.parseFile( reportProfile, "global" );
expctxCheck = new BExpressionContext("way");
expctxCheck.readMetaData( lookupFile );
expctxCheck.parseFile( checkProfile, "global" );
// *** read the relation file into a set (currently cycleway processing only) // *** read the relation file into a set (currently cycleway processing only)
cyclewayset = new CompactLongSet(); cyclewayset = new CompactLongSet();
DataInputStream dis = createInStream( relationFileIn ); DataInputStream dis = createInStream( relationFileIn );
try try
{ {
for(;;)
{
long rid = readId( dis );
String network = dis.readUTF();
boolean goodNetwork = "lcn".equals( network ) || "rcn".equals( network ) || "ncn".equals( network ) || "icn".equals( network );
for(;;) for(;;)
{ {
long wid = readId( dis ); long wid = readId( dis );
if ( !cyclewayset.contains( wid ) ) cyclewayset.add( wid ); if ( wid == -1 ) break;
if ( goodNetwork && !cyclewayset.contains( wid ) ) cyclewayset.add( wid );
}
} }
} }
catch( EOFException eof ) catch( EOFException eof )
{ {
dis.close(); dis.close();
} }
cyclewayset = new FrozenLongSet( cyclewayset );
System.out.println( "marked cycleways: " + cyclewayset.size() ); System.out.println( "marked cycleways: " + cyclewayset.size() );
@ -75,9 +97,22 @@ public class WayCutter extends MapCreatorBase
{ {
// propagate the cycleway-bit // propagate the cycleway-bit
if ( cyclewayset.contains( data.wid ) ) if ( cyclewayset.contains( data.wid ) )
{
// check access and log a warning for conflicts
expctxCheck.evaluate( data.description, null );
boolean ok = expctxCheck.getCostfactor() < 10000.;
expctxReport.evaluate( data.description, null );
boolean warn = expctxReport.getCostfactor() >= 10000.;
if ( warn )
{
System.out.println( "** relation access conflict for wid = " + data.wid + " tags:" + expctxReport.getKeyValueDescription( data.description ) + " (ok=" + ok + ")" );
}
if ( ok )
{ {
data.description |= 2; data.description |= 2;
} }
}
long waytileset = 0; long waytileset = 0;
int nnodes = data.nodes.size(); int nnodes = data.nodes.size();

View file

@ -64,7 +64,7 @@ public class WayLinker extends MapCreatorBase
this.borderFileIn = borderFileIn; this.borderFileIn = borderFileIn;
this.dataTilesSuffix = dataTilesSuffix; this.dataTilesSuffix = dataTilesSuffix;
// read lookup file to get the lookup-version // read lookup + profile for lookup-version + access-filter
expctxWay = new BExpressionContext("way"); expctxWay = new BExpressionContext("way");
expctxWay.readMetaData( lookupFile ); expctxWay.readMetaData( lookupFile );
lookupVersion = expctxWay.lookupVersion; lookupVersion = expctxWay.lookupVersion;

View file

@ -34,9 +34,11 @@ public class MapcreatorTest
new NodeFilter().process( nodetiles, wayFile, ftiles ); new NodeFilter().process( nodetiles, wayFile, ftiles );
// run WayCutter // run WayCutter
File profileReport = new File( workingDir, "trekking.brf" );
File profileCheck = new File( workingDir, "softaccess.brf" );
File waytiles = new File( tmpdir, "waytiles" ); File waytiles = new File( tmpdir, "waytiles" );
waytiles.mkdir(); waytiles.mkdir();
new WayCutter().process( ftiles, wayFile, waytiles, relFile ); new WayCutter().process( ftiles, wayFile, waytiles, relFile, lookupFile, profileReport, profileCheck );
// run WayCutter5 // run WayCutter5
File waytiles55 = new File( tmpdir, "waytiles55" ); File waytiles55 = new File( tmpdir, "waytiles55" );

View file

@ -0,0 +1,21 @@
# *** soft-access check used to prevent setting the cyclewaybit on motorroads
---context:global # following code refers to global config
assign validForBikes 1
---context:way # following code refers to way-tags
assign costfactor
#
# exclude motorways, proposed roads and motorroads
#
switch or highway=motorway highway=motorway_link 100000
switch highway=proposed 100000
switch motorroad=yes 100000
1.0
---context:node # following code refers to node tags

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

View file

@ -20,7 +20,7 @@ mkdir ftiles
/java/bin/java -Xmx512M -Xms512M -Xmn32M -cp ../brouter.jar -Ddeletetmpfiles=true -DuseDenseMaps=true btools.mapcreator.NodeFilter nodetiles ways.dat ftiles /java/bin/java -Xmx512M -Xms512M -Xmn32M -cp ../brouter.jar -Ddeletetmpfiles=true -DuseDenseMaps=true btools.mapcreator.NodeFilter nodetiles ways.dat ftiles
mkdir waytiles mkdir waytiles
/java/bin/java -Xmx2600M -Xms2600M -Xmn32M -cp ../brouter.jar -Ddeletetmpfiles=true -DuseDenseMaps=true btools.mapcreator.WayCutter ftiles ways.dat waytiles cycleways.dat /java/bin/java -Xmx2600M -Xms2600M -Xmn32M -cp ../brouter.jar -Ddeletetmpfiles=true -DuseDenseMaps=true btools.mapcreator.WayCutter ftiles ways.dat waytiles cycleways.dat ../lookups.dat ../trekking.brf ../softaccess.brf
mkdir waytiles55 mkdir waytiles55
/java/bin/java -Xmx2600M -Xms2600M -Xmn32M -cp ../brouter.jar -Ddeletetmpfiles=true -DuseDenseMaps=true btools.mapcreator.WayCutter5 ftiles waytiles waytiles55 bordernids.dat /java/bin/java -Xmx2600M -Xms2600M -Xmn32M -cp ../brouter.jar -Ddeletetmpfiles=true -DuseDenseMaps=true btools.mapcreator.WayCutter5 ftiles waytiles waytiles55 bordernids.dat

View file

@ -0,0 +1,21 @@
# *** soft-access check used to prevent setting the cyclewaybit on motorroads
---context:global # following code refers to global config
assign validForBikes 1
---context:way # following code refers to way-tags
assign costfactor
#
# exclude motorways, proposed roads and motorroads
#
switch or highway=motorway highway=motorway_link 100000
switch highway=proposed 100000
switch motorroad=yes 100000
1.0
---context:node # following code refers to node tags