network and access checks on cycle relations
This commit is contained in:
parent
2b70d8a862
commit
1b8c3ccea8
10 changed files with 409 additions and 10 deletions
|
@ -168,6 +168,22 @@ public final class BExpressionContext
|
|||
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 )
|
||||
{
|
||||
try
|
||||
|
|
|
@ -174,11 +174,16 @@ public class OsmCutter extends MapCreatorBase
|
|||
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++ )
|
||||
{
|
||||
long wid = r.ways.get(i);
|
||||
writeId( cyclewayDos, wid );
|
||||
}
|
||||
writeId( cyclewayDos, -1 );
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -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" );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -4,8 +4,10 @@ import java.io.DataInputStream;
|
|||
import java.io.EOFException;
|
||||
import java.io.File;
|
||||
|
||||
import btools.expressions.BExpressionContext;
|
||||
import btools.util.CompactLongSet;
|
||||
import btools.util.DenseLongMap;
|
||||
import btools.util.FrozenLongSet;
|
||||
import btools.util.TinyDenseLongMap;
|
||||
|
||||
/**
|
||||
|
@ -20,23 +22,33 @@ public class WayCutter extends MapCreatorBase
|
|||
{
|
||||
private CompactLongSet cyclewayset;
|
||||
private DenseLongMap tileIndexMap;
|
||||
private BExpressionContext expctxReport;
|
||||
private BExpressionContext expctxCheck;
|
||||
|
||||
public static void main(String[] args) throws Exception
|
||||
{
|
||||
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;
|
||||
}
|
||||
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;
|
||||
|
||||
// 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)
|
||||
cyclewayset = new CompactLongSet();
|
||||
DataInputStream dis = createInStream( relationFileIn );
|
||||
|
@ -44,14 +56,24 @@ public class WayCutter extends MapCreatorBase
|
|||
{
|
||||
for(;;)
|
||||
{
|
||||
long wid = readId( dis );
|
||||
if ( !cyclewayset.contains( wid ) ) cyclewayset.add( wid );
|
||||
long rid = readId( dis );
|
||||
String network = dis.readUTF();
|
||||
boolean goodNetwork = "lcn".equals( network ) || "rcn".equals( network ) || "ncn".equals( network ) || "icn".equals( network );
|
||||
|
||||
for(;;)
|
||||
{
|
||||
long wid = readId( dis );
|
||||
if ( wid == -1 ) break;
|
||||
if ( goodNetwork && !cyclewayset.contains( wid ) ) cyclewayset.add( wid );
|
||||
}
|
||||
}
|
||||
}
|
||||
catch( EOFException eof )
|
||||
{
|
||||
dis.close();
|
||||
}
|
||||
|
||||
cyclewayset = new FrozenLongSet( cyclewayset );
|
||||
System.out.println( "marked cycleways: " + cyclewayset.size() );
|
||||
|
||||
|
||||
|
@ -76,7 +98,20 @@ public class WayCutter extends MapCreatorBase
|
|||
// propagate the cycleway-bit
|
||||
if ( cyclewayset.contains( data.wid ) )
|
||||
{
|
||||
data.description |= 2;
|
||||
// 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;
|
||||
}
|
||||
}
|
||||
|
||||
long waytileset = 0;
|
||||
|
|
|
@ -64,7 +64,7 @@ public class WayLinker extends MapCreatorBase
|
|||
this.borderFileIn = borderFileIn;
|
||||
this.dataTilesSuffix = dataTilesSuffix;
|
||||
|
||||
// read lookup file to get the lookup-version
|
||||
// read lookup + profile for lookup-version + access-filter
|
||||
expctxWay = new BExpressionContext("way");
|
||||
expctxWay.readMetaData( lookupFile );
|
||||
lookupVersion = expctxWay.lookupVersion;
|
||||
|
|
|
@ -34,9 +34,11 @@ public class MapcreatorTest
|
|||
new NodeFilter().process( nodetiles, wayFile, ftiles );
|
||||
|
||||
// run WayCutter
|
||||
File profileReport = new File( workingDir, "trekking.brf" );
|
||||
File profileCheck = new File( workingDir, "softaccess.brf" );
|
||||
File waytiles = new File( tmpdir, "waytiles" );
|
||||
waytiles.mkdir();
|
||||
new WayCutter().process( ftiles, wayFile, waytiles, relFile );
|
||||
new WayCutter().process( ftiles, wayFile, waytiles, relFile, lookupFile, profileReport, profileCheck );
|
||||
|
||||
// run WayCutter5
|
||||
File waytiles55 = new File( tmpdir, "waytiles55" );
|
||||
|
|
21
brouter-map-creator/src/test/resources/softaccess.brf
Normal file
21
brouter-map-creator/src/test/resources/softaccess.brf
Normal 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
|
||||
|
225
brouter-map-creator/src/test/resources/trekking.brf
Normal file
225
brouter-map-creator/src/test/resources/trekking.brf
Normal 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
|
|
@ -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
|
||||
|
||||
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
|
||||
/java/bin/java -Xmx2600M -Xms2600M -Xmn32M -cp ../brouter.jar -Ddeletetmpfiles=true -DuseDenseMaps=true btools.mapcreator.WayCutter5 ftiles waytiles waytiles55 bordernids.dat
|
||||
|
|
21
misc/scripts/mapcreation/softaccess.brf
Normal file
21
misc/scripts/mapcreation/softaccess.brf
Normal 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
|
||||
|
Loading…
Reference in a new issue