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

@ -1,6 +1,5 @@
package btools.codec; package btools.codec;
import java.util.BitSet;
import java.util.HashMap; import java.util.HashMap;
import btools.util.ByteDataReader; import btools.util.ByteDataReader;
@ -88,14 +87,33 @@ public final class MicroCache2 extends MicroCache
int ilon = alon[n]; int ilon = alon[n];
int ilat = alat[n]; int ilat = alat[n];
// future feature escape (turn restrictions?) // future escapes (turn restrictions?)
for(;;) for(;;)
{ {
int featureId = bc.decodeVarBits(); int featureId = bc.decodeVarBits();
if ( featureId == 0 ) break; if ( featureId == 0 ) break;
int bitsize = bc.decodeNoisyNumber( 5 ); int bitsize = bc.decodeNoisyNumber( 5 );
for( int i=0; i< bitsize; i++ ) bc.decodeBit(); // just skip
if ( featureId == 1 ) // turn-restriction
{
if ( bitsize != 1 + 4*29 )
{
throw new RuntimeException( "turn-restriction of unexpected bit-size: " + bitsize );
} }
writeBoolean( true );
writeBoolean( bc.decodeBit() ); // isPositive
int max = (1 << 29) - 1;
writeInt( bc.decodeBounded( max ) ); // fromLon, ...
writeInt( bc.decodeBounded( max ) );
writeInt( bc.decodeBounded( max ) );
writeInt( bc.decodeBounded( max ) );
}
else
{
for( int i=0; i< bitsize; i++ ) bc.decodeBit(); // unknown feature, just skip
}
}
writeBoolean( false );
selev += nodeEleDiff.decodeSignedValue(); selev += nodeEleDiff.decodeSignedValue();
writeShort( (short) selev ); writeShort( (short) selev );
@ -342,8 +360,22 @@ public final class MicroCache2 extends MicroCache
aboffsetEnd = fapos[n]; aboffsetEnd = fapos[n];
if ( dodebug ) System.out.println( "*** encoding node " + n + " from " + aboffset + " to " + aboffsetEnd ); if ( dodebug ) System.out.println( "*** encoding node " + n + " from " + aboffset + " to " + aboffsetEnd );
// future feature escape (turn restrictions?) // write turn restrictions
bc.encodeVarBits( 0 ); while( readBoolean() )
{
bc.encodeVarBits( 1 ); // 1 = extra-data type : turn-restriction
bc.encodeNoisyNumber( 1 + 4*29, 5 );
bc.encodeBit( readBoolean() ); // isPositive
int max = (1 << 29) - 1;
bc.encodeBounded( max, readInt() ); // fromLon
bc.encodeBounded( max, readInt() ); // fromLat
bc.encodeBounded( max, readInt() ); // toLon
bc.encodeBounded( max, readInt() ); // toLat
}
bc.encodeVarBits( 0 ); // end of extra data
if ( dostats ) bc.assignBits( "extradata" );
int selev = readShort(); int selev = readShort();
nodeEleDiff.encodeSignedValue( selev - lastSelev ); nodeEleDiff.encodeSignedValue( selev - lastSelev );

View file

@ -11,6 +11,7 @@ import btools.mapaccess.OsmLink;
import btools.mapaccess.OsmLinkHolder; import btools.mapaccess.OsmLinkHolder;
import btools.mapaccess.OsmNode; import btools.mapaccess.OsmNode;
import btools.mapaccess.OsmTransferNode; import btools.mapaccess.OsmTransferNode;
import btools.mapaccess.TurnRestriction;
final class OsmPath implements OsmLinkHolder final class OsmPath implements OsmLinkHolder
{ {
@ -174,6 +175,8 @@ final class OsmPath implements OsmLinkHolder
OsmTransferNode transferNode = link.geometry == null ? null OsmTransferNode transferNode = link.geometry == null ? null
: rc.geometryDecoder.decodeGeometry( link.geometry, p1, targetNode, isReverse ); : rc.geometryDecoder.decodeGeometry( link.geometry, p1, targetNode, isReverse );
boolean isFirstSection = true;
for(;;) for(;;)
{ {
originLon = lon1; originLon = lon1;
@ -196,6 +199,43 @@ final class OsmPath implements OsmLinkHolder
ele2 = transferNode.selev; ele2 = transferNode.selev;
} }
// check turn restrictions: do we have one with that origin?
if ( isFirstSection && rc.considerTurnRestrictions )
{
isFirstSection = false;
boolean hasAnyPositive = false;
boolean hasPositive = false;
boolean hasNegative = false;
TurnRestriction tr = sourceNode.firstRestriction;
while( tr != null )
{
if ( tr.fromLon == lon0 && tr.fromLat == lat0 )
{
if ( tr.isPositive )
{
hasAnyPositive = true;
}
if ( tr.toLon == lon2 && tr.toLat == lat2 )
{
if ( tr.isPositive )
{
hasPositive = true;
}
else
{
hasNegative = true;
}
}
}
tr = tr.next;
}
if ( !hasPositive && ( hasAnyPositive || hasNegative ) )
{
cost = -1;
return;
}
}
// if recording, new MessageData for each section (needed for turn-instructions) // if recording, new MessageData for each section (needed for turn-instructions)
if ( recordMessageData && msgData.wayKeyValues != null ) if ( recordMessageData && msgData.wayKeyValues != null )
{ {

View file

@ -53,6 +53,7 @@ public final class RoutingContext
public int uphillcutoff; public int uphillcutoff;
public boolean carMode; public boolean carMode;
public boolean bikeMode; public boolean bikeMode;
public boolean considerTurnRestrictions;
public boolean forceSecondaryData; public boolean forceSecondaryData;
public double pass1coefficient; public double pass1coefficient;
public double pass2coefficient; public double pass2coefficient;
@ -80,6 +81,9 @@ public final class RoutingContext
carMode = 0.f != expctxGlobal.getVariableValue( "validForCars", 0.f ); carMode = 0.f != expctxGlobal.getVariableValue( "validForCars", 0.f );
bikeMode = 0.f != expctxGlobal.getVariableValue( "validForBikes", 0.f ); bikeMode = 0.f != expctxGlobal.getVariableValue( "validForBikes", 0.f );
// turn-restrictions used per default for car profiles
considerTurnRestrictions = 0.f != expctxGlobal.getVariableValue( "considerTurnRestrictions", carMode ? 1.f : 0.f );
forceSecondaryData = 0.f != expctxGlobal.getVariableValue( "forceSecondaryData", 0.f ); forceSecondaryData = 0.f != expctxGlobal.getVariableValue( "forceSecondaryData", 0.f );
pass1coefficient = expctxGlobal.getVariableValue( "pass1coefficient", 1.5f ); pass1coefficient = expctxGlobal.getVariableValue( "pass1coefficient", 1.5f );
pass2coefficient = expctxGlobal.getVariableValue( "pass2coefficient", 0.f ); pass2coefficient = expctxGlobal.getVariableValue( "pass2coefficient", 0.f );

View file

@ -164,4 +164,8 @@ public abstract class MapCreatorBase implements WayListener, NodeListener, Relat
@Override @Override
public void nextRelation( RelationData data ) throws Exception {} 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 wayDos;
private DataOutputStream cyclewayDos; private DataOutputStream cyclewayDos;
private DataOutputStream restrictionsDos;
public static void main(String[] args) throws Exception public static void main(String[] args) throws Exception
{ {
System.out.println("*** OsmCutter: cut an osm map in node-tiles + a way file"); 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("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> <filter-profile> <inputfile> "); System.out.println("or : java OsmCutter <lookup-file> <out-tile-dir> <out-way-file> <out-rel-file> <out-res-file> <filter-profile> <inputfile> ");
return; return;
} }
@ -44,7 +45,8 @@ public class OsmCutter extends MapCreatorBase
, new File( args[2] ) , new File( args[2] )
, new File( args[3] ) , new File( args[3] )
, new File( args[4] ) , 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 BExpressionContextWay _expctxWayStat;
private BExpressionContextNode _expctxNodeStat; 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() ) if ( !lookupFile.exists() )
{ {
@ -77,6 +79,7 @@ public class OsmCutter extends MapCreatorBase
wayDos = new DataOutputStream( new BufferedOutputStream( new FileOutputStream( wayFile ) ) ); wayDos = new DataOutputStream( new BufferedOutputStream( new FileOutputStream( wayFile ) ) );
cyclewayDos = new DataOutputStream( new BufferedOutputStream( new FileOutputStream( relFile ) ) ); cyclewayDos = new DataOutputStream( new BufferedOutputStream( new FileOutputStream( relFile ) ) );
restrictionsDos = new DataOutputStream( new BufferedOutputStream( new FileOutputStream( resFile ) ) );
// read the osm map into memory // read the osm map into memory
long t0 = System.currentTimeMillis(); long t0 = System.currentTimeMillis();
@ -89,11 +92,12 @@ public class OsmCutter extends MapCreatorBase
closeTileOutStreams(); closeTileOutStreams();
wayDos.close(); wayDos.close();
cyclewayDos.close(); cyclewayDos.close();
restrictionsDos.close();
System.out.println( "-------- way-statistics -------- " ); // System.out.println( "-------- way-statistics -------- " );
_expctxWayStat.dumpStatistics(); // _expctxWayStat.dumpStatistics();
System.out.println( "-------- node-statistics -------- " ); // System.out.println( "-------- node-statistics -------- " );
_expctxNodeStat.dumpStatistics(); // _expctxNodeStat.dumpStatistics();
System.out.println( statsLine() ); System.out.println( statsLine() );
} }
@ -194,6 +198,41 @@ public class OsmCutter extends MapCreatorBase
writeId( cyclewayDos, -1 ); 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 ) private int getTileIndex( int ilon, int ilat )
{ {

View file

@ -96,6 +96,11 @@ public class OsmNodeP extends OsmLinkP
return null; return null;
} }
public RestrictionData getFirstRestriction()
{
return null;
}
public void writeNodeData( MicroCache mc ) throws IOException public void writeNodeData( MicroCache mc ) throws IOException
{ {
boolean valid = true; boolean valid = true;
@ -164,6 +169,21 @@ public class OsmNodeP extends OsmLinkP
public boolean writeNodeData2( MicroCache2 mc ) throws IOException public boolean writeNodeData2( MicroCache2 mc ) throws IOException
{ {
boolean hasLinks = false; 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.writeShort( getSElev() );
mc.writeVarBytes( getNodeDecsription() ); 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 * @author ab
*/ */
@ -10,10 +10,20 @@ public class OsmNodePT extends OsmNodeP
{ {
public byte[] descriptionBits; public byte[] descriptionBits;
public RestrictionData firstRestriction;
public OsmNodePT() public OsmNodePT()
{ {
} }
public OsmNodePT( OsmNodeP n )
{
ilat = n.ilat;
ilon = n.ilon;
selev = n.selev;
bits = n.bits;
}
public OsmNodePT( byte[] descriptionBits ) public OsmNodePT( byte[] descriptionBits )
{ {
this.descriptionBits = descriptionBits; this.descriptionBits = descriptionBits;
@ -25,6 +35,12 @@ public class OsmNodePT extends OsmNodeP
return descriptionBits; return descriptionBits;
} }
@Override
public final RestrictionData getFirstRestriction()
{
return firstRestriction;
}
@Override @Override
public boolean isTransferNode() public boolean isTransferNode()
{ {

View file

@ -9,4 +9,6 @@ package btools.mapcreator;
public interface RelationListener public interface RelationListener
{ {
void nextRelation( RelationData data ) throws Exception; 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; package btools.mapcreator;
import java.io.BufferedInputStream;
import java.io.ByteArrayOutputStream; import java.io.ByteArrayOutputStream;
import java.io.DataInputStream;
import java.io.DataOutputStream; import java.io.DataOutputStream;
import java.io.EOFException;
import java.io.File; import java.io.File;
import java.io.FileInputStream;
import java.io.RandomAccessFile; import java.io.RandomAccessFile;
import java.util.List; import java.util.List;
import java.util.TreeMap; import java.util.TreeMap;
@ -34,6 +38,7 @@ public class WayLinker extends MapCreatorBase
private File trafficTilesIn; private File trafficTilesIn;
private File dataTilesOut; private File dataTilesOut;
private File borderFileIn; private File borderFileIn;
private File restrictionsFileIn;
private String dataTilesSuffix; private String dataTilesSuffix;
@ -70,23 +75,24 @@ public class WayLinker extends MapCreatorBase
public static void main( String[] args ) throws Exception public static void main( String[] args ) throws Exception
{ {
System.out.println( "*** WayLinker: Format a region of an OSM map for routing" ); System.out.println( "*** WayLinker: Format a region of an OSM map for routing" );
if ( args.length != 7 ) if ( args.length != 8 )
{ {
System.out 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; 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( 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[5] ), args[6] ); 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 String dataTilesSuffix ) throws Exception
{ {
this.nodeTilesIn = nodeTilesIn; this.nodeTilesIn = nodeTilesIn;
this.trafficTilesIn = new File( "traffic" ); this.trafficTilesIn = new File( "traffic" );
this.dataTilesOut = dataTilesOut; this.dataTilesOut = dataTilesOut;
this.borderFileIn = borderFileIn; this.borderFileIn = borderFileIn;
this.restrictionsFileIn = restrictionsFileIn;
this.dataTilesSuffix = dataTilesSuffix; this.dataTilesSuffix = dataTilesSuffix;
BExpressionMetaData meta = new BExpressionMetaData(); BExpressionMetaData meta = new BExpressionMetaData();
@ -135,6 +141,36 @@ public class WayLinker extends MapCreatorBase
// freeze the nodes-map // freeze the nodes-map
FrozenLongMap<OsmNodeP> nodesMapFrozen = new FrozenLongMap<OsmNodeP>( nodesMap ); FrozenLongMap<OsmNodeP> nodesMapFrozen = new FrozenLongMap<OsmNodeP>( nodesMap );
nodesMap = nodesMapFrozen; 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(); nodesList = nodesMapFrozen.getValueList();
} }
@ -178,6 +214,43 @@ public class WayLinker extends MapCreatorBase
throw new IllegalArgumentException( "inconsistent node: " + n.ilon + " " + n.ilat ); 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 @Override
public void nextWay( WayData way ) throws Exception public void nextWay( WayData way ) throws Exception
{ {
@ -209,6 +282,8 @@ public class WayLinker extends MapCreatorBase
if ( n1 != null && n2 != null && n1 != n2 ) if ( n1 != null && n2 != null && n1 != n2 )
{ {
checkRestriction( n1, n2, way );
OsmLinkP link = n2.createLink( n1 ); OsmLinkP link = n2.createLink( n1 );
int traffic = trafficMap == null ? 0 : trafficMap.getTrafficClass( n1.getIdFromPos(), n2.getIdFromPos() ); 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 lookupFile = new File( profileDir, "lookups.dat" );
File wayFile = new File( tmpdir, "ways.dat" ); File wayFile = new File( tmpdir, "ways.dat" );
File relFile = new File( tmpdir, "cycleways.dat" ); File relFile = new File( tmpdir, "cycleways.dat" );
File resFile = new File( tmpdir, "restrictions.dat" );
File profileAllFile = new File( profileDir, "all.brf" ); 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 // run NodeFilter
File ftiles = new File( tmpdir, "ftiles" ); File ftiles = new File( tmpdir, "ftiles" );
@ -66,6 +67,6 @@ public class MapcreatorTest
// run WayLinker // run WayLinker
File segments = new File( tmpdir, "segments" ); File segments = new File( tmpdir, "segments" );
segments.mkdir(); segments.mkdir();
new WayLinker().process( unodes55, waytiles55, bordernodes, lookupFile, profileAllFile, segments, "rd5" ); new WayLinker().process( unodes55, waytiles55, bordernodes, resFile, lookupFile, profileAllFile, segments, "rd5" );
} }
} }

View file

@ -33,6 +33,8 @@ public class OsmNode extends OsmLink implements OsmPos
*/ */
public byte[] nodeDescription; public byte[] nodeDescription;
public TurnRestriction firstRestriction;
/** /**
* The links to other nodes * The links to other nodes
*/ */
@ -130,6 +132,22 @@ public class OsmNode extends OsmLink implements OsmPos
{ {
ByteArrayUnifier abUnifier = hollowNodes.getByteArrayUnifier(); ByteArrayUnifier abUnifier = hollowNodes.getByteArrayUnifier();
// read turn restrictions
while( mc.readBoolean() )
{
TurnRestriction tr = new TurnRestriction();
tr.isPositive = mc.readBoolean();
tr.fromLon = mc.readInt();
tr.fromLat = mc.readInt();
tr.toLon = mc.readInt();
tr.toLat = mc.readInt();
tr.next = firstRestriction;
firstRestriction = tr;
System.out.println( "decoded tr: " + tr );
}
selev = mc.readShort(); selev = mc.readShort();
int nodeDescSize = mc.readVarLengthUnsigned(); int nodeDescSize = mc.readVarLengthUnsigned();
nodeDescription = nodeDescSize == 0 ? null : mc.readUnified( nodeDescSize, abUnifier ); nodeDescription = nodeDescSize == 0 ? null : mc.readUnified( nodeDescSize, abUnifier );

View file

@ -0,0 +1,26 @@
/**
* Container for a turn restriction
*
* @author ab
*/
package btools.mapaccess;
public final class TurnRestriction
{
public boolean isPositive;
public int fromLon;
public int fromLat;
public int toLon;
public int toLat;
public TurnRestriction next;
@Override
public String toString()
{
return "pos=" + isPositive + " fromLon=" + fromLon + " fromLat=" + fromLat + " toLon=" + toLon + " toLat=" + toLat;
}
}

View file

@ -21,7 +21,7 @@ public class CompactLongMap<V>
private int size = 0; private int size = 0;
private int _maxKeepExponent = 14; // the maximum exponent to keep the invalid arrays private int _maxKeepExponent = 14; // the maximum exponent to keep the invalid arrays
private V value_in; protected V value_in;
protected V value_out; protected V value_out;
protected static final int MAXLISTS = 31; // enough for size Integer.MAX_VALUE protected static final int MAXLISTS = 31; // enough for size Integer.MAX_VALUE

View file

@ -33,7 +33,20 @@ public class FrozenLongMap<V> extends CompactLongMap<V>
@Override @Override
public boolean put( long id, V value ) public boolean put( long id, V value )
{ {
throw new RuntimeException( "cannot put on FrozenLongIntMap" ); try
{
value_in = value;
if ( contains( id, true ) )
{
return true;
}
throw new RuntimeException( "cannot only put on existing key in FrozenLongIntMap" );
}
finally
{
value_in = null;
value_out = null;
}
} }
@Override @Override
@ -79,14 +92,17 @@ public class FrozenLongMap<V> extends CompactLongMap<V>
if ( a[n] == id ) if ( a[n] == id )
{ {
value_out = flv.get(n); value_out = flv.get(n);
if ( doPut )
{
flv.set( n, value_in );
}
return true; return true;
} }
return false; return false;
} }
/** /**
* @return the value for "id", * @return the value for "id", or null if key unknown
* Throw an exception if not contained in the map.
*/ */
@Override @Override
public V get( long id ) public V get( long id )

View file

@ -210,12 +210,17 @@ public class BPbfBlobDecoder
} }
} }
private long fromWid;
private long toWid;
private long viaNid;
private LongList buildRelationMembers( private LongList buildRelationMembers(
List<Long> memberIds, List<Integer> memberRoles, List<Osmformat.Relation.MemberType> memberTypes, List<Long> memberIds, List<Integer> memberRoles, List<Osmformat.Relation.MemberType> memberTypes,
BPbfFieldDecoder fieldDecoder ) BPbfFieldDecoder fieldDecoder )
{ {
LongList wayIds = new LongList( 16 ); LongList wayIds = new LongList( 16 );
fromWid = toWid = viaNid = 0;
Iterator<Long> memberIdIterator = memberIds.iterator(); Iterator<Long> memberIdIterator = memberIds.iterator();
Iterator<Integer> memberRoleIterator = memberRoles.iterator(); Iterator<Integer> memberRoleIterator = memberRoles.iterator();
@ -235,6 +240,12 @@ public class BPbfBlobDecoder
if ( memberType == Osmformat.Relation.MemberType.WAY ) // currently just waymembers if ( memberType == Osmformat.Relation.MemberType.WAY ) // currently just waymembers
{ {
wayIds.add( refId ); wayIds.add( refId );
if ( "from".equals( role ) ) fromWid = refId;
if ( "to".equals( role ) ) toWid = refId;
}
if ( memberType == Osmformat.Relation.MemberType.NODE ) // currently just waymembers
{
if ( "via".equals( role ) ) viaNid = refId;
} }
} }
return wayIds; return wayIds;
@ -249,7 +260,7 @@ public class BPbfBlobDecoder
LongList wayIds = buildRelationMembers( relation.getMemidsList(), relation.getRolesSidList(), LongList wayIds = buildRelationMembers( relation.getMemidsList(), relation.getRolesSidList(),
relation.getTypesList(), fieldDecoder); relation.getTypesList(), fieldDecoder);
parser.addRelation( relation.getId(), tags, wayIds ); parser.addRelation( relation.getId(), tags, wayIds, fromWid, toWid, viaNid );
} }
} }

View file

@ -92,7 +92,7 @@ public class OsmParser extends MapCreatorBase
} }
} }
public void addRelation( long rid, Map<String, String> tags, LongList wayIds ) public void addRelation( long rid, Map<String, String> tags, LongList wayIds, long fromWid, long toWid, long viaNid )
{ {
RelationData r = new RelationData( rid, wayIds ); RelationData r = new RelationData( rid, wayIds );
r.setTags( (HashMap<String,String>)tags ); r.setTags( (HashMap<String,String>)tags );
@ -100,6 +100,7 @@ public class OsmParser extends MapCreatorBase
try try
{ {
rListener.nextRelation( r ); rListener.nextRelation( r );
rListener.nextRestriction( r, fromWid, toWid, viaNid );
} }
catch( Exception e ) catch( Exception e )
{ {

View file

@ -1 +1 @@
javac -d . -cp protobuf.jar;osmosis.jar;brouter.jar BPbfFieldDecoder.java BPbfBlobDecoder.java OsmParser.java javac -d . -cp pbfparser.jar;brouter.jar BPbfFieldDecoder.java BPbfBlobDecoder.java OsmParser.java