added turn restrictions

This commit is contained in:
Arndt 2016-11-20 22:31:10 +01:00
parent 561b60c5cb
commit e48cbd49cb
18 changed files with 383 additions and 32 deletions

View file

@ -164,4 +164,8 @@ public abstract class MapCreatorBase implements WayListener, NodeListener, Relat
@Override
public void nextRelation( RelationData data ) throws Exception {}
@Override
public void nextRestriction( RelationData data, long fromWid, long toWid, long viaNid ) throws Exception {}
}

View file

@ -27,14 +27,15 @@ public class OsmCutter extends MapCreatorBase
private DataOutputStream wayDos;
private DataOutputStream cyclewayDos;
private DataOutputStream restrictionsDos;
public static void main(String[] args) throws Exception
{
System.out.println("*** OsmCutter: cut an osm map in node-tiles + a way file");
if (args.length != 5 && args.length != 6)
if (args.length != 6 && args.length != 7)
{
System.out.println("usage: bzip2 -dc <map> | java OsmCutter <lookup-file> <out-tile-dir> <out-way-file> <out-rel-file> <filter-profile>");
System.out.println("or : java OsmCutter <lookup-file> <out-tile-dir> <out-way-file> <out-rel-file> <filter-profile> <inputfile> ");
System.out.println("usage: bzip2 -dc <map> | java OsmCutter <lookup-file> <out-tile-dir> <out-way-file> <out-rel-file> <out-res-file> <filter-profile>");
System.out.println("or : java OsmCutter <lookup-file> <out-tile-dir> <out-way-file> <out-rel-file> <out-res-file> <filter-profile> <inputfile> ");
return;
}
@ -44,7 +45,8 @@ public class OsmCutter extends MapCreatorBase
, new File( args[2] )
, new File( args[3] )
, new File( args[4] )
, args.length > 5 ? new File( args[5] ) : null
, new File( args[5] )
, args.length > 6 ? new File( args[6] ) : null
);
}
@ -54,7 +56,7 @@ public class OsmCutter extends MapCreatorBase
private BExpressionContextWay _expctxWayStat;
private BExpressionContextNode _expctxNodeStat;
public void process (File lookupFile, File outTileDir, File wayFile, File relFile, File profileFile, File mapFile ) throws Exception
public void process (File lookupFile, File outTileDir, File wayFile, File relFile, File resFile, File profileFile, File mapFile ) throws Exception
{
if ( !lookupFile.exists() )
{
@ -77,6 +79,7 @@ public class OsmCutter extends MapCreatorBase
wayDos = new DataOutputStream( new BufferedOutputStream( new FileOutputStream( wayFile ) ) );
cyclewayDos = new DataOutputStream( new BufferedOutputStream( new FileOutputStream( relFile ) ) );
restrictionsDos = new DataOutputStream( new BufferedOutputStream( new FileOutputStream( resFile ) ) );
// read the osm map into memory
long t0 = System.currentTimeMillis();
@ -89,11 +92,12 @@ public class OsmCutter extends MapCreatorBase
closeTileOutStreams();
wayDos.close();
cyclewayDos.close();
restrictionsDos.close();
System.out.println( "-------- way-statistics -------- " );
_expctxWayStat.dumpStatistics();
System.out.println( "-------- node-statistics -------- " );
_expctxNodeStat.dumpStatistics();
// System.out.println( "-------- way-statistics -------- " );
// _expctxWayStat.dumpStatistics();
// System.out.println( "-------- node-statistics -------- " );
// _expctxNodeStat.dumpStatistics();
System.out.println( statsLine() );
}
@ -194,6 +198,41 @@ public class OsmCutter extends MapCreatorBase
writeId( cyclewayDos, -1 );
}
@Override
public void nextRestriction( RelationData r, long fromWid, long toWid, long viaNid ) throws Exception
{
if ( fromWid == 0 || toWid == 0 || viaNid == 0 )
{
return;
}
String type = r.getTag( "type" );
if ( type == null || !"restriction".equals( type ) )
{
return;
}
String restriction = r.getTag( "restriction" );
if ( restriction == null )
{
return;
}
boolean isPositive = true;
if ( restriction.startsWith( "no_" ) )
{
isPositive = false;
}
else if ( !restriction.startsWith( "only_" ) )
{
return;
}
// System.out.println( "restriction id = " + r.rid + " isPositive=" + isPositive + " fromWid = " + fromWid + " toWid = " + toWid+ " viaNid = " + viaNid );
RestrictionData res = new RestrictionData();
res.isPositive = isPositive;
res.fromWid = fromWid;
res.toWid = toWid;
res.viaNid = viaNid;
res.writeTo( restrictionsDos );
}
private int getTileIndex( int ilon, int ilat )
{

View file

@ -96,6 +96,11 @@ public class OsmNodeP extends OsmLinkP
return null;
}
public RestrictionData getFirstRestriction()
{
return null;
}
public void writeNodeData( MicroCache mc ) throws IOException
{
boolean valid = true;
@ -164,6 +169,21 @@ public class OsmNodeP extends OsmLinkP
public boolean writeNodeData2( MicroCache2 mc ) throws IOException
{
boolean hasLinks = false;
// write turn restrictions
RestrictionData r = getFirstRestriction();
while( r != null )
{
mc.writeBoolean( true ); // restriction follows
mc.writeBoolean( r.isPositive );
mc.writeInt( r.fromLon );
mc.writeInt( r.fromLat );
mc.writeInt( r.toLon );
mc.writeInt( r.toLat );
r = r.next;
}
mc.writeBoolean( false ); // end restritions
mc.writeShort( getSElev() );
mc.writeVarBytes( getNodeDecsription() );

View file

@ -1,5 +1,5 @@
/**
* Container for an osm node with tags (pre-pocessor version)
* Container for an osm node with tags or restrictions (pre-pocessor version)
*
* @author ab
*/
@ -10,10 +10,20 @@ public class OsmNodePT extends OsmNodeP
{
public byte[] descriptionBits;
public RestrictionData firstRestriction;
public OsmNodePT()
{
}
public OsmNodePT( OsmNodeP n )
{
ilat = n.ilat;
ilon = n.ilon;
selev = n.selev;
bits = n.bits;
}
public OsmNodePT( byte[] descriptionBits )
{
this.descriptionBits = descriptionBits;
@ -25,6 +35,12 @@ public class OsmNodePT extends OsmNodeP
return descriptionBits;
}
@Override
public final RestrictionData getFirstRestriction()
{
return firstRestriction;
}
@Override
public boolean isTransferNode()
{

View file

@ -9,4 +9,6 @@ package btools.mapcreator;
public interface RelationListener
{
void nextRelation( RelationData data ) throws Exception;
void nextRestriction( RelationData data, long fromWid, long toWid, long viaNid ) throws Exception;
}

View file

@ -0,0 +1,46 @@
package btools.mapcreator;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import btools.util.LongList;
/**
* Container for a turn restriction
*
* @author ab
*/
public class RestrictionData extends MapCreatorBase
{
public boolean isPositive;
public long fromWid;
public long toWid;
public long viaNid;
public RestrictionData next;
public int fromLon;
public int fromLat;
public int toLon;
public int toLat;
public RestrictionData()
{
}
public RestrictionData( DataInputStream di ) throws Exception
{
isPositive = di.readBoolean();
fromWid = readId( di );
toWid = readId( di );
viaNid = readId( di );
}
public void writeTo( DataOutputStream dos ) throws Exception
{
dos.writeBoolean( isPositive );
writeId( dos, fromWid );
writeId( dos, toWid );
writeId( dos, viaNid );
}
}

View file

@ -1,8 +1,12 @@
package btools.mapcreator;
import java.io.BufferedInputStream;
import java.io.ByteArrayOutputStream;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.EOFException;
import java.io.File;
import java.io.FileInputStream;
import java.io.RandomAccessFile;
import java.util.List;
import java.util.TreeMap;
@ -34,6 +38,7 @@ public class WayLinker extends MapCreatorBase
private File trafficTilesIn;
private File dataTilesOut;
private File borderFileIn;
private File restrictionsFileIn;
private String dataTilesSuffix;
@ -70,23 +75,24 @@ public class WayLinker extends MapCreatorBase
public static void main( String[] args ) throws Exception
{
System.out.println( "*** WayLinker: Format a region of an OSM map for routing" );
if ( args.length != 7 )
if ( args.length != 8 )
{
System.out
.println( "usage: java WayLinker <node-tiles-in> <way-tiles-in> <bordernodes> <lookup-file> <profile-file> <data-tiles-out> <data-tiles-suffix> " );
.println( "usage: java WayLinker <node-tiles-in> <way-tiles-in> <bordernodes> <restrictions> <lookup-file> <profile-file> <data-tiles-out> <data-tiles-suffix> " );
return;
}
new WayLinker().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] ), args[6] );
new WayLinker().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] ), args[7] );
}
public void process( File nodeTilesIn, File wayTilesIn, File borderFileIn, File lookupFile, File profileFile, File dataTilesOut,
public void process( File nodeTilesIn, File wayTilesIn, File borderFileIn, File restrictionsFileIn, File lookupFile, File profileFile, File dataTilesOut,
String dataTilesSuffix ) throws Exception
{
this.nodeTilesIn = nodeTilesIn;
this.trafficTilesIn = new File( "traffic" );
this.dataTilesOut = dataTilesOut;
this.borderFileIn = borderFileIn;
this.restrictionsFileIn = restrictionsFileIn;
this.dataTilesSuffix = dataTilesSuffix;
BExpressionMetaData meta = new BExpressionMetaData();
@ -135,6 +141,36 @@ public class WayLinker extends MapCreatorBase
// freeze the nodes-map
FrozenLongMap<OsmNodeP> nodesMapFrozen = new FrozenLongMap<OsmNodeP>( nodesMap );
nodesMap = nodesMapFrozen;
// read restrictions for nodes in nodesMap
DataInputStream di = new DataInputStream( new BufferedInputStream ( new FileInputStream( restrictionsFileIn ) ) );
int ntr = 0;
try
{
for(;;)
{
RestrictionData res = new RestrictionData( di );
OsmNodeP n = nodesMap.get( res.viaNid );
if ( n != null )
{
if ( ! ( n instanceof OsmNodePT ) )
{
n = new OsmNodePT( n );
nodesMap.put( res.viaNid, n );
}
OsmNodePT nt = (OsmNodePT) n;
res.next = nt.firstRestriction;
nt.firstRestriction = res;
ntr++;
}
}
}
catch( EOFException eof )
{
di.close();
}
System.out.println( "read " + ntr + " turn-restrictions" );
nodesList = nodesMapFrozen.getValueList();
}
@ -178,6 +214,43 @@ public class WayLinker extends MapCreatorBase
throw new IllegalArgumentException( "inconsistent node: " + n.ilon + " " + n.ilat );
}
// check if one of the nodes has a turn-restriction with
// the current way as from or to member.
// It seems to be required, that each member of a turn-restriction
// starts or ends at it's via node. However, we allow
// ways not ending at the via node, and in this case we take
// the leg according to the mapped direction
private void checkRestriction( OsmNodeP n1, OsmNodeP n2, WayData w )
{
checkRestriction( n1, n2, w.wid, true );
checkRestriction( n2, n1, w.wid, false );
}
private void checkRestriction( OsmNodeP n1, OsmNodeP n2, long wid, boolean checkFrom )
{
RestrictionData r = n2.getFirstRestriction();
while ( r != null )
{
if ( r.fromWid == wid )
{
if ( r.fromLon == 0 || checkFrom )
{
r.fromLon = n1.ilon;
r.fromLat = n1.ilat;
}
}
if ( r.toWid == wid )
{
if ( r.toLon == 0 || !checkFrom )
{
r.toLon = n1.ilon;
r.toLat = n1.ilat;
}
}
r = r.next;
}
}
@Override
public void nextWay( WayData way ) throws Exception
{
@ -209,6 +282,8 @@ public class WayLinker extends MapCreatorBase
if ( n1 != null && n2 != null && n1 != n2 )
{
checkRestriction( n1, n2, way );
OsmLinkP link = n2.createLink( n1 );
int traffic = trafficMap == null ? 0 : trafficMap.getTrafficClass( n1.getIdFromPos(), n2.getIdFromPos() );

View file

@ -27,8 +27,9 @@ public class MapcreatorTest
File lookupFile = new File( profileDir, "lookups.dat" );
File wayFile = new File( tmpdir, "ways.dat" );
File relFile = new File( tmpdir, "cycleways.dat" );
File resFile = new File( tmpdir, "restrictions.dat" );
File profileAllFile = new File( profileDir, "all.brf" );
new OsmCutter().process( lookupFile, nodetiles, wayFile, relFile, profileAllFile, mapfile );
new OsmCutter().process( lookupFile, nodetiles, wayFile, relFile, resFile, profileAllFile, mapfile );
// run NodeFilter
File ftiles = new File( tmpdir, "ftiles" );
@ -66,6 +67,6 @@ public class MapcreatorTest
// run WayLinker
File segments = new File( tmpdir, "segments" );
segments.mkdir();
new WayLinker().process( unodes55, waytiles55, bordernodes, lookupFile, profileAllFile, segments, "rd5" );
new WayLinker().process( unodes55, waytiles55, bordernodes, resFile, lookupFile, profileAllFile, segments, "rd5" );
}
}