added turn restrictions
This commit is contained in:
parent
561b60c5cb
commit
e48cbd49cb
18 changed files with 383 additions and 32 deletions
|
@ -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 );
|
||||||
|
|
|
@ -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 )
|
||||||
{
|
{
|
||||||
|
|
|
@ -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 );
|
||||||
|
|
|
@ -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 {}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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 )
|
||||||
{
|
{
|
||||||
|
|
|
@ -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() );
|
||||||
|
|
||||||
|
|
|
@ -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()
|
||||||
{
|
{
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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 );
|
||||||
|
}
|
||||||
|
}
|
|
@ -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() );
|
||||||
|
|
|
@ -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" );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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 );
|
||||||
|
|
|
@ -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;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -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
|
||||||
|
|
|
@ -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 )
|
||||||
|
|
|
@ -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 );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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 )
|
||||||
{
|
{
|
||||||
|
|
|
@ -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
|
||||||
|
|
Loading…
Reference in a new issue