diff --git a/brouter-codec/src/main/java/btools/codec/MicroCache2.java b/brouter-codec/src/main/java/btools/codec/MicroCache2.java index 79291bb..a9ca5db 100644 --- a/brouter-codec/src/main/java/btools/codec/MicroCache2.java +++ b/brouter-codec/src/main/java/btools/codec/MicroCache2.java @@ -1,6 +1,5 @@ package btools.codec; -import java.util.BitSet; import java.util.HashMap; import btools.util.ByteDataReader; @@ -88,14 +87,33 @@ public final class MicroCache2 extends MicroCache int ilon = alon[n]; int ilat = alat[n]; - // future feature escape (turn restrictions?) + // future escapes (turn restrictions?) for(;;) { int featureId = bc.decodeVarBits(); if ( featureId == 0 ) break; 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(); writeShort( (short) selev ); @@ -341,9 +359,23 @@ public final class MicroCache2 extends MicroCache aboffset = startPos( n ); aboffsetEnd = fapos[n]; if ( dodebug ) System.out.println( "*** encoding node " + n + " from " + aboffset + " to " + aboffsetEnd ); - - // future feature escape (turn restrictions?) - bc.encodeVarBits( 0 ); + + // write turn restrictions + 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(); nodeEleDiff.encodeSignedValue( selev - lastSelev ); diff --git a/brouter-core/src/main/java/btools/router/OsmPath.java b/brouter-core/src/main/java/btools/router/OsmPath.java index a87ea9c..f9c2357 100644 --- a/brouter-core/src/main/java/btools/router/OsmPath.java +++ b/brouter-core/src/main/java/btools/router/OsmPath.java @@ -11,6 +11,7 @@ import btools.mapaccess.OsmLink; import btools.mapaccess.OsmLinkHolder; import btools.mapaccess.OsmNode; import btools.mapaccess.OsmTransferNode; +import btools.mapaccess.TurnRestriction; final class OsmPath implements OsmLinkHolder { @@ -174,6 +175,8 @@ final class OsmPath implements OsmLinkHolder OsmTransferNode transferNode = link.geometry == null ? null : rc.geometryDecoder.decodeGeometry( link.geometry, p1, targetNode, isReverse ); + boolean isFirstSection = true; + for(;;) { originLon = lon1; @@ -195,7 +198,44 @@ final class OsmPath implements OsmLinkHolder lat2 = transferNode.ilat; 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 ( recordMessageData && msgData.wayKeyValues != null ) { diff --git a/brouter-core/src/main/java/btools/router/RoutingContext.java b/brouter-core/src/main/java/btools/router/RoutingContext.java index d6278c9..0195209 100644 --- a/brouter-core/src/main/java/btools/router/RoutingContext.java +++ b/brouter-core/src/main/java/btools/router/RoutingContext.java @@ -53,6 +53,7 @@ public final class RoutingContext public int uphillcutoff; public boolean carMode; public boolean bikeMode; + public boolean considerTurnRestrictions; public boolean forceSecondaryData; public double pass1coefficient; public double pass2coefficient; @@ -80,6 +81,9 @@ public final class RoutingContext carMode = 0.f != expctxGlobal.getVariableValue( "validForCars", 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 ); pass1coefficient = expctxGlobal.getVariableValue( "pass1coefficient", 1.5f ); pass2coefficient = expctxGlobal.getVariableValue( "pass2coefficient", 0.f ); diff --git a/brouter-map-creator/src/main/java/btools/mapcreator/MapCreatorBase.java b/brouter-map-creator/src/main/java/btools/mapcreator/MapCreatorBase.java index 0f128f8..f7c7b0a 100644 --- a/brouter-map-creator/src/main/java/btools/mapcreator/MapCreatorBase.java +++ b/brouter-map-creator/src/main/java/btools/mapcreator/MapCreatorBase.java @@ -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 {} + } diff --git a/brouter-map-creator/src/main/java/btools/mapcreator/OsmCutter.java b/brouter-map-creator/src/main/java/btools/mapcreator/OsmCutter.java index dd42fcd..173cff0 100644 --- a/brouter-map-creator/src/main/java/btools/mapcreator/OsmCutter.java +++ b/brouter-map-creator/src/main/java/btools/mapcreator/OsmCutter.java @@ -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 | java OsmCutter "); - System.out.println("or : java OsmCutter "); + System.out.println("usage: bzip2 -dc | java OsmCutter "); + System.out.println("or : java OsmCutter "); 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 ) { diff --git a/brouter-map-creator/src/main/java/btools/mapcreator/OsmNodeP.java b/brouter-map-creator/src/main/java/btools/mapcreator/OsmNodeP.java index 5621d6e..004a7fd 100644 --- a/brouter-map-creator/src/main/java/btools/mapcreator/OsmNodeP.java +++ b/brouter-map-creator/src/main/java/btools/mapcreator/OsmNodeP.java @@ -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() ); diff --git a/brouter-map-creator/src/main/java/btools/mapcreator/OsmNodePT.java b/brouter-map-creator/src/main/java/btools/mapcreator/OsmNodePT.java index f8eda68..4286671 100644 --- a/brouter-map-creator/src/main/java/btools/mapcreator/OsmNodePT.java +++ b/brouter-map-creator/src/main/java/btools/mapcreator/OsmNodePT.java @@ -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() { diff --git a/brouter-map-creator/src/main/java/btools/mapcreator/RelationListener.java b/brouter-map-creator/src/main/java/btools/mapcreator/RelationListener.java index 6d51486..34bae75 100644 --- a/brouter-map-creator/src/main/java/btools/mapcreator/RelationListener.java +++ b/brouter-map-creator/src/main/java/btools/mapcreator/RelationListener.java @@ -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; } diff --git a/brouter-map-creator/src/main/java/btools/mapcreator/RestrictionData.java b/brouter-map-creator/src/main/java/btools/mapcreator/RestrictionData.java new file mode 100644 index 0000000..9784287 --- /dev/null +++ b/brouter-map-creator/src/main/java/btools/mapcreator/RestrictionData.java @@ -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 ); + } +} diff --git a/brouter-map-creator/src/main/java/btools/mapcreator/WayLinker.java b/brouter-map-creator/src/main/java/btools/mapcreator/WayLinker.java index e77d116..6c4bd23 100644 --- a/brouter-map-creator/src/main/java/btools/mapcreator/WayLinker.java +++ b/brouter-map-creator/src/main/java/btools/mapcreator/WayLinker.java @@ -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 " ); + .println( "usage: java WayLinker " ); 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 nodesMapFrozen = new FrozenLongMap( 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() ); diff --git a/brouter-map-creator/src/test/java/btools/mapcreator/MapcreatorTest.java b/brouter-map-creator/src/test/java/btools/mapcreator/MapcreatorTest.java index 4da0bd5..a90b659 100644 --- a/brouter-map-creator/src/test/java/btools/mapcreator/MapcreatorTest.java +++ b/brouter-map-creator/src/test/java/btools/mapcreator/MapcreatorTest.java @@ -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" ); } } diff --git a/brouter-mapaccess/src/main/java/btools/mapaccess/OsmNode.java b/brouter-mapaccess/src/main/java/btools/mapaccess/OsmNode.java index f68b27e..8e1b3e5 100644 --- a/brouter-mapaccess/src/main/java/btools/mapaccess/OsmNode.java +++ b/brouter-mapaccess/src/main/java/btools/mapaccess/OsmNode.java @@ -32,6 +32,8 @@ public class OsmNode extends OsmLink implements OsmPos * The node-tags, if any */ public byte[] nodeDescription; + + public TurnRestriction firstRestriction; /** * The links to other nodes @@ -129,6 +131,22 @@ public class OsmNode extends OsmLink implements OsmPos public final void parseNodeBody2( MicroCache2 mc, OsmNodesMap hollowNodes, IByteArrayUnifier expCtxWay ) { 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(); int nodeDescSize = mc.readVarLengthUnsigned(); diff --git a/brouter-mapaccess/src/main/java/btools/mapaccess/TurnRestriction.java b/brouter-mapaccess/src/main/java/btools/mapaccess/TurnRestriction.java new file mode 100644 index 0000000..d8924fc --- /dev/null +++ b/brouter-mapaccess/src/main/java/btools/mapaccess/TurnRestriction.java @@ -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; + } + +} diff --git a/brouter-util/src/main/java/btools/util/CompactLongMap.java b/brouter-util/src/main/java/btools/util/CompactLongMap.java index 314772b..80943c5 100644 --- a/brouter-util/src/main/java/btools/util/CompactLongMap.java +++ b/brouter-util/src/main/java/btools/util/CompactLongMap.java @@ -21,7 +21,7 @@ public class CompactLongMap private int size = 0; 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 static final int MAXLISTS = 31; // enough for size Integer.MAX_VALUE diff --git a/brouter-util/src/main/java/btools/util/FrozenLongMap.java b/brouter-util/src/main/java/btools/util/FrozenLongMap.java index ff53e3a..168a948 100644 --- a/brouter-util/src/main/java/btools/util/FrozenLongMap.java +++ b/brouter-util/src/main/java/btools/util/FrozenLongMap.java @@ -33,9 +33,22 @@ public class FrozenLongMap extends CompactLongMap @Override 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 public void fastPut( long id, V value ) { @@ -79,14 +92,17 @@ public class FrozenLongMap extends CompactLongMap if ( a[n] == id ) { value_out = flv.get(n); + if ( doPut ) + { + flv.set( n, value_in ); + } return true; } return false; } /** - * @return the value for "id", - * Throw an exception if not contained in the map. + * @return the value for "id", or null if key unknown */ @Override public V get( long id ) diff --git a/misc/pbfparser/BPbfBlobDecoder.java b/misc/pbfparser/BPbfBlobDecoder.java index 2db9dad..4bd47e1 100644 --- a/misc/pbfparser/BPbfBlobDecoder.java +++ b/misc/pbfparser/BPbfBlobDecoder.java @@ -210,12 +210,17 @@ public class BPbfBlobDecoder } } + private long fromWid; + private long toWid; + private long viaNid; + private LongList buildRelationMembers( List memberIds, List memberRoles, List memberTypes, BPbfFieldDecoder fieldDecoder ) { LongList wayIds = new LongList( 16 ); + fromWid = toWid = viaNid = 0; Iterator memberIdIterator = memberIds.iterator(); Iterator memberRoleIterator = memberRoles.iterator(); @@ -235,6 +240,12 @@ public class BPbfBlobDecoder if ( memberType == Osmformat.Relation.MemberType.WAY ) // currently just waymembers { 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; @@ -249,7 +260,7 @@ public class BPbfBlobDecoder LongList wayIds = buildRelationMembers( relation.getMemidsList(), relation.getRolesSidList(), relation.getTypesList(), fieldDecoder); - parser.addRelation( relation.getId(), tags, wayIds ); + parser.addRelation( relation.getId(), tags, wayIds, fromWid, toWid, viaNid ); } } diff --git a/misc/pbfparser/OsmParser.java b/misc/pbfparser/OsmParser.java index 76105e1..7fd22bd 100644 --- a/misc/pbfparser/OsmParser.java +++ b/misc/pbfparser/OsmParser.java @@ -92,7 +92,7 @@ public class OsmParser extends MapCreatorBase } } - public void addRelation( long rid, Map tags, LongList wayIds ) + public void addRelation( long rid, Map tags, LongList wayIds, long fromWid, long toWid, long viaNid ) { RelationData r = new RelationData( rid, wayIds ); r.setTags( (HashMap)tags ); @@ -100,6 +100,7 @@ public class OsmParser extends MapCreatorBase try { rListener.nextRelation( r ); + rListener.nextRestriction( r, fromWid, toWid, viaNid ); } catch( Exception e ) { diff --git a/misc/pbfparser/compile_parser.bat b/misc/pbfparser/compile_parser.bat index 6036270..7a5452b 100644 --- a/misc/pbfparser/compile_parser.bat +++ b/misc/pbfparser/compile_parser.bat @@ -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