1.0 preparations
This commit is contained in:
parent
55717c6e71
commit
8fa82633d4
34 changed files with 742 additions and 462 deletions
|
@ -50,13 +50,13 @@ public final class RoutingContext implements DistanceChecker
|
||||||
|
|
||||||
public void readGlobalConfig( BExpressionContext expctxGlobal )
|
public void readGlobalConfig( BExpressionContext expctxGlobal )
|
||||||
{
|
{
|
||||||
downhillcostdiv = (int)expctxGlobal.getVariableValue( "downhillcost" );
|
downhillcostdiv = (int)expctxGlobal.getVariableValue( "downhillcost", 0.f );
|
||||||
downhillcutoff = (int)(expctxGlobal.getVariableValue( "downhillcutoff" )*10000);
|
downhillcutoff = (int)(expctxGlobal.getVariableValue( "downhillcutoff", 0.f )*10000);
|
||||||
uphillcostdiv = (int)expctxGlobal.getVariableValue( "uphillcost" );
|
uphillcostdiv = (int)expctxGlobal.getVariableValue( "uphillcost", 0.f );
|
||||||
uphillcutoff = (int)(expctxGlobal.getVariableValue( "uphillcutoff" )*10000);
|
uphillcutoff = (int)(expctxGlobal.getVariableValue( "uphillcutoff", 0.f )*10000);
|
||||||
if ( downhillcostdiv != 0 ) downhillcostdiv = 1000000/downhillcostdiv;
|
if ( downhillcostdiv != 0 ) downhillcostdiv = 1000000/downhillcostdiv;
|
||||||
if ( uphillcostdiv != 0 ) uphillcostdiv = 1000000/uphillcostdiv;
|
if ( uphillcostdiv != 0 ) uphillcostdiv = 1000000/uphillcostdiv;
|
||||||
carMode = 0.f != expctxGlobal.getVariableValue( "validForCars" );
|
carMode = 0.f != expctxGlobal.getVariableValue( "validForCars", 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 );
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,6 +5,7 @@ import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import btools.expressions.BExpressionContext;
|
import btools.expressions.BExpressionContext;
|
||||||
|
import btools.expressions.BExpressionMetaData;
|
||||||
import btools.mapaccess.NodesCache;
|
import btools.mapaccess.NodesCache;
|
||||||
import btools.mapaccess.OsmLink;
|
import btools.mapaccess.OsmLink;
|
||||||
import btools.mapaccess.OsmLinkHolder;
|
import btools.mapaccess.OsmLinkHolder;
|
||||||
|
@ -70,18 +71,20 @@ public class RoutingEngine extends Thread
|
||||||
profileDir = new File( profileBaseDir );
|
profileDir = new File( profileBaseDir );
|
||||||
profileFile = new File( profileDir, rc.localFunction + ".brf" ) ;
|
profileFile = new File( profileDir, rc.localFunction + ".brf" ) ;
|
||||||
}
|
}
|
||||||
BExpressionContext expctxGlobal = new BExpressionContext( "global" );
|
|
||||||
expctxGlobal.readMetaData( new File( profileDir, "lookups.dat" ) );
|
BExpressionMetaData meta = new BExpressionMetaData();
|
||||||
|
|
||||||
|
BExpressionContext expctxGlobal = new BExpressionContext( "global", meta );
|
||||||
|
rc.expctxWay = new BExpressionContext( "way", meta );
|
||||||
|
rc.expctxNode = new BExpressionContext( "node", 1024, meta );
|
||||||
|
|
||||||
|
meta.readMetaData( new File( profileDir, "lookups.dat" ) );
|
||||||
|
|
||||||
expctxGlobal.parseFile( profileFile, null );
|
expctxGlobal.parseFile( profileFile, null );
|
||||||
expctxGlobal.evaluate( new int[0] );
|
expctxGlobal.evaluate( new int[0] );
|
||||||
rc.readGlobalConfig(expctxGlobal);
|
rc.readGlobalConfig(expctxGlobal);
|
||||||
|
|
||||||
rc.expctxWay = new BExpressionContext( "way", 4096 );
|
|
||||||
rc.expctxWay.readMetaData( new File( profileDir, "lookups.dat" ) );
|
|
||||||
rc.expctxWay.parseFile( profileFile, "global" );
|
rc.expctxWay.parseFile( profileFile, "global" );
|
||||||
|
|
||||||
rc.expctxNode = new BExpressionContext( "node", 1024 );
|
|
||||||
rc.expctxNode.readMetaData( new File( profileDir, "lookups.dat" ) );
|
|
||||||
rc.expctxNode.parseFile( profileFile, "global" );
|
rc.expctxNode.parseFile( profileFile, "global" );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -372,7 +375,6 @@ public class RoutingEngine extends Thread
|
||||||
if ( matchPath != null )
|
if ( matchPath != null )
|
||||||
{
|
{
|
||||||
track = mergeTrack( matchPath, nearbyTrack );
|
track = mergeTrack( matchPath, nearbyTrack );
|
||||||
isDirty = true;
|
|
||||||
}
|
}
|
||||||
maxRunningTime += System.currentTimeMillis() - startTime; // reset timeout...
|
maxRunningTime += System.currentTimeMillis() - startTime; // reset timeout...
|
||||||
}
|
}
|
||||||
|
@ -432,7 +434,8 @@ public class RoutingEngine extends Thread
|
||||||
private void resetCache()
|
private void resetCache()
|
||||||
{
|
{
|
||||||
nodesMap = new OsmNodesMap();
|
nodesMap = new OsmNodesMap();
|
||||||
nodesCache = new NodesCache(segmentDir, nodesMap, routingContext.expctxWay.lookupVersion,routingContext.expctxWay.lookupMinorVersion, routingContext.carMode, nodesCache );
|
BExpressionContext ctx = routingContext.expctxWay;
|
||||||
|
nodesCache = new NodesCache(segmentDir, nodesMap, ctx.meta.lookupVersion, ctx.meta.lookupMinorVersion, ctx.meta.readVarLength, routingContext.carMode, nodesCache );
|
||||||
}
|
}
|
||||||
|
|
||||||
private OsmNode getStartNode( long startId )
|
private OsmNode getStartNode( long startId )
|
||||||
|
@ -566,11 +569,13 @@ public class RoutingEngine extends Thread
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private OsmTrack findTrack( String operationName, MatchedWaypoint startWp, MatchedWaypoint endWp, OsmTrack costCuttingTrack, OsmTrack refTrack, boolean reducedTimeoutWhenUnmatched )
|
private OsmTrack findTrack( String operationName, MatchedWaypoint startWp, MatchedWaypoint endWp, OsmTrack costCuttingTrack, OsmTrack refTrack, boolean fastPartialRecalc )
|
||||||
{
|
{
|
||||||
boolean verbose = guideTrack != null;
|
boolean verbose = guideTrack != null;
|
||||||
|
|
||||||
int maxTotalCost = 1000000000;
|
int maxTotalCost = 1000000000;
|
||||||
|
int firstMatchCost = 1000000000;
|
||||||
|
int firstEstimate = 1000000000;
|
||||||
|
|
||||||
logInfo( "findtrack with maxTotalCost=" + maxTotalCost + " airDistanceCostFactor=" + airDistanceCostFactor );
|
logInfo( "findtrack with maxTotalCost=" + maxTotalCost + " airDistanceCostFactor=" + airDistanceCostFactor );
|
||||||
|
|
||||||
|
@ -607,7 +612,7 @@ public class RoutingEngine extends Thread
|
||||||
{
|
{
|
||||||
if ( maxRunningTime > 0 )
|
if ( maxRunningTime > 0 )
|
||||||
{
|
{
|
||||||
long timeout = ( matchPath == null && reducedTimeoutWhenUnmatched ) ? maxRunningTime/3 : maxRunningTime;
|
long timeout = ( matchPath == null && fastPartialRecalc ) ? maxRunningTime/3 : maxRunningTime;
|
||||||
if ( System.currentTimeMillis() - startTime > timeout )
|
if ( System.currentTimeMillis() - startTime > timeout )
|
||||||
{
|
{
|
||||||
throw new IllegalArgumentException( operationName + " timeout after " + (timeout/1000) + " seconds" );
|
throw new IllegalArgumentException( operationName + " timeout after " + (timeout/1000) + " seconds" );
|
||||||
|
@ -627,6 +632,11 @@ public class RoutingEngine extends Thread
|
||||||
}
|
}
|
||||||
maxAdjCostFromQueue = path.adjustedCost;
|
maxAdjCostFromQueue = path.adjustedCost;
|
||||||
|
|
||||||
|
if ( matchPath != null && fastPartialRecalc && firstMatchCost < 500 && path.cost > 30L*firstMatchCost )
|
||||||
|
{
|
||||||
|
throw new IllegalArgumentException( "early exit for a close recalc" );
|
||||||
|
}
|
||||||
|
|
||||||
nodesVisited++;
|
nodesVisited++;
|
||||||
linksProcessed++;
|
linksProcessed++;
|
||||||
|
|
||||||
|
@ -645,6 +655,32 @@ public class RoutingEngine extends Thread
|
||||||
logInfo( "found track at cost " + path.cost + " nodesVisited = " + nodesVisited );
|
logInfo( "found track at cost " + path.cost + " nodesVisited = " + nodesVisited );
|
||||||
return compileTrack( path, verbose );
|
return compileTrack( path, verbose );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// check for a match with the cost-cutting-track
|
||||||
|
if ( costCuttingTrack != null )
|
||||||
|
{
|
||||||
|
OsmPathElement pe = costCuttingTrack.getLink( sourceNodeId, currentNodeId );
|
||||||
|
if ( pe != null )
|
||||||
|
{
|
||||||
|
// remember first match cost for fast termination of partial recalcs
|
||||||
|
int parentcost = path.originElement == null ? 0 : path.originElement.cost;
|
||||||
|
if ( parentcost < firstMatchCost ) firstMatchCost = parentcost;
|
||||||
|
|
||||||
|
int costEstimate = path.cost
|
||||||
|
+ path.elevationCorrection( routingContext )
|
||||||
|
+ ( costCuttingTrack.cost - pe.cost );
|
||||||
|
if ( costEstimate <= maxTotalCost )
|
||||||
|
{
|
||||||
|
if ( matchPath == null ) firstEstimate = costEstimate;
|
||||||
|
matchPath = new OsmPathElement( path );
|
||||||
|
}
|
||||||
|
if ( costEstimate < maxTotalCost )
|
||||||
|
{
|
||||||
|
logInfo( "maxcost " + maxTotalCost + " -> " + costEstimate );
|
||||||
|
maxTotalCost = costEstimate;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// recheck cutoff before doing expensive stuff
|
// recheck cutoff before doing expensive stuff
|
||||||
|
@ -743,27 +779,6 @@ public class RoutingEngine extends Thread
|
||||||
int airDistance = isFinalLink ? 0 : nextNode.calcDistance( endPos );
|
int airDistance = isFinalLink ? 0 : nextNode.calcDistance( endPos );
|
||||||
bestPath.setAirDistanceCostAdjustment( (int)( airDistance * airDistanceCostFactor ) );
|
bestPath.setAirDistanceCostAdjustment( (int)( airDistance * airDistanceCostFactor ) );
|
||||||
|
|
||||||
// check for a match with the cost-cutting-track
|
|
||||||
if ( costCuttingTrack != null )
|
|
||||||
{
|
|
||||||
OsmPathElement pe = costCuttingTrack.getLink( currentNodeId, targetNodeId );
|
|
||||||
if ( pe != null )
|
|
||||||
{
|
|
||||||
int costEstimate = bestPath.cost
|
|
||||||
+ bestPath.elevationCorrection( routingContext )
|
|
||||||
+ ( costCuttingTrack.cost - pe.cost );
|
|
||||||
if ( costEstimate <= maxTotalCost )
|
|
||||||
{
|
|
||||||
matchPath = new OsmPathElement( bestPath );
|
|
||||||
}
|
|
||||||
if ( costEstimate < maxTotalCost )
|
|
||||||
{
|
|
||||||
logInfo( "maxcost " + maxTotalCost + " -> " + costEstimate + " airDistance=" + airDistance );
|
|
||||||
maxTotalCost = costEstimate;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( isFinalLink || bestPath.cost + airDistance <= maxTotalCost + 10 )
|
if ( isFinalLink || bestPath.cost + airDistance <= maxTotalCost + 10 )
|
||||||
{
|
{
|
||||||
// add only if this may beat an existing path for that link
|
// add only if this may beat an existing path for that link
|
||||||
|
|
|
@ -23,11 +23,8 @@ import btools.util.Crc32;
|
||||||
|
|
||||||
public final class BExpressionContext
|
public final class BExpressionContext
|
||||||
{
|
{
|
||||||
private static final String CONTEXT_TAG = "---context:";
|
private static final String CONTEXT_TAG = "---context:";
|
||||||
private static final String VERSION_TAG = "---lookupversion:";
|
|
||||||
private static final String MINOR_VERSION_TAG = "---minorversion:";
|
|
||||||
private static final String VARLENGTH_TAG = "---readvarlength";
|
|
||||||
|
|
||||||
private String context;
|
private String context;
|
||||||
private boolean _inOurContext = false;
|
private boolean _inOurContext = false;
|
||||||
private BufferedReader _br = null;
|
private BufferedReader _br = null;
|
||||||
|
@ -55,7 +52,6 @@ public final class BExpressionContext
|
||||||
private byte[][] _arrayBitmap;
|
private byte[][] _arrayBitmap;
|
||||||
private int currentHashBucket = -1;
|
private int currentHashBucket = -1;
|
||||||
private byte[] currentByteArray = null;
|
private byte[] currentByteArray = null;
|
||||||
private boolean currentInversion = false;
|
|
||||||
|
|
||||||
public List<BExpression> expressionList;
|
public List<BExpression> expressionList;
|
||||||
|
|
||||||
|
@ -79,13 +75,12 @@ public final class BExpressionContext
|
||||||
|
|
||||||
private int linenr;
|
private int linenr;
|
||||||
|
|
||||||
public short lookupVersion = -1;
|
public BExpressionMetaData meta;
|
||||||
public short lookupMinorVersion = -1;
|
private boolean lookupDataValid = false;
|
||||||
public boolean readVarLength = false;
|
|
||||||
|
|
||||||
public BExpressionContext( String context )
|
public BExpressionContext( String context, BExpressionMetaData meta )
|
||||||
{
|
{
|
||||||
this( context, 4096 );
|
this( context, 4096, meta );
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -94,9 +89,15 @@ public final class BExpressionContext
|
||||||
* @param context global, way or node - context of that instance
|
* @param context global, way or node - context of that instance
|
||||||
* @param hashSize size of hashmap for result caching
|
* @param hashSize size of hashmap for result caching
|
||||||
*/
|
*/
|
||||||
public BExpressionContext( String context, int hashSize )
|
public BExpressionContext( String context, int hashSize, BExpressionMetaData meta )
|
||||||
{
|
{
|
||||||
this.context = context;
|
this.context = context;
|
||||||
|
this.meta = meta;
|
||||||
|
|
||||||
|
meta.registerListener(context, this );
|
||||||
|
|
||||||
|
if ( Boolean.getBoolean( "disableExpressionCache" ) ) hashSize = 1;
|
||||||
|
|
||||||
_arrayBitmap = new byte[hashSize][];
|
_arrayBitmap = new byte[hashSize][];
|
||||||
|
|
||||||
_arrayCostfactor = new float[hashSize];
|
_arrayCostfactor = new float[hashSize];
|
||||||
|
@ -105,18 +106,18 @@ public final class BExpressionContext
|
||||||
_arrayNodeAccessGranted = new float[hashSize];
|
_arrayNodeAccessGranted = new float[hashSize];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* encode internal lookup data to a byte array
|
* encode internal lookup data to a byte array
|
||||||
*/
|
*/
|
||||||
public byte[] encode()
|
public byte[] encode()
|
||||||
{
|
{
|
||||||
|
if ( !lookupDataValid ) throw new IllegalArgumentException( "internal error: encoding undefined data?" );
|
||||||
return encode( lookupData );
|
return encode( lookupData );
|
||||||
}
|
}
|
||||||
|
|
||||||
public byte[] encode( int[] ld )
|
public byte[] encode( int[] ld )
|
||||||
{
|
{
|
||||||
if ( !readVarLength ) return encodeFix( ld );
|
if ( !meta.readVarLength ) return encodeFix( ld );
|
||||||
|
|
||||||
// start with first bit hardwired ("reversedirection")
|
// start with first bit hardwired ("reversedirection")
|
||||||
BitCoderContext ctx = new BitCoderContext( abBuf );
|
BitCoderContext ctx = new BitCoderContext( abBuf );
|
||||||
|
@ -134,16 +135,16 @@ public final class BExpressionContext
|
||||||
skippedTags++;
|
skippedTags++;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
ctx.encodeDistance( skippedTags+1 );
|
ctx.encodeVarBits( skippedTags+1 );
|
||||||
nonNullTags++;
|
nonNullTags++;
|
||||||
skippedTags = 0;
|
skippedTags = 0;
|
||||||
|
|
||||||
// 0 excluded already, 1 (=unknown) we rotate up to 8
|
// 0 excluded already, 1 (=unknown) we rotate up to 8
|
||||||
// to have the good code space for the popular values
|
// to have the good code space for the popular values
|
||||||
int dd = d < 2 ? 7 : ( d < 9 ? d - 2 : d - 1);
|
int dd = d < 2 ? 7 : ( d < 9 ? d - 2 : d - 1);
|
||||||
ctx.encodeDistance( dd );
|
ctx.encodeVarBits( dd );
|
||||||
}
|
}
|
||||||
ctx.encodeDistance( 0 );
|
ctx.encodeVarBits( 0 );
|
||||||
|
|
||||||
if ( nonNullTags == 0) return null;
|
if ( nonNullTags == 0) return null;
|
||||||
|
|
||||||
|
@ -200,6 +201,7 @@ public final class BExpressionContext
|
||||||
public void decode( byte[] ab )
|
public void decode( byte[] ab )
|
||||||
{
|
{
|
||||||
decode( lookupData, ab );
|
decode( lookupData, ab );
|
||||||
|
lookupDataValid = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -207,7 +209,7 @@ public final class BExpressionContext
|
||||||
*/
|
*/
|
||||||
public void decode( int[] ld, byte[] ab )
|
public void decode( int[] ld, byte[] ab )
|
||||||
{
|
{
|
||||||
if ( !readVarLength ) { decodeFix( ld, ab ); return; }
|
if ( !meta.readVarLength ) { decodeFix( ld, ab ); return; }
|
||||||
|
|
||||||
BitCoderContext ctx = new BitCoderContext(ab);
|
BitCoderContext ctx = new BitCoderContext(ab);
|
||||||
|
|
||||||
|
@ -218,14 +220,14 @@ public final class BExpressionContext
|
||||||
int inum = 1;
|
int inum = 1;
|
||||||
for(;;)
|
for(;;)
|
||||||
{
|
{
|
||||||
int delta = ctx.decodeDistance();
|
int delta = ctx.decodeVarBits();
|
||||||
if ( delta == 0) break;
|
if ( delta == 0) break;
|
||||||
if ( inum + delta > ld.length ) break; // higher minor version is o.k.
|
if ( inum + delta > ld.length ) break; // higher minor version is o.k.
|
||||||
|
|
||||||
while ( delta-- > 1 ) ld[inum++] = 0;
|
while ( delta-- > 1 ) ld[inum++] = 0;
|
||||||
|
|
||||||
// see encoder for value rotation
|
// see encoder for value rotation
|
||||||
int dd = ctx.decodeDistance();
|
int dd = ctx.decodeVarBits();
|
||||||
int d = dd == 7 ? 1 : ( dd < 7 ? dd + 2 : dd + 1);
|
int d = dd == 7 ? 1 : ( dd < 7 ? dd + 2 : dd + 1);
|
||||||
if ( d >= lookupValues.get(inum).length ) d = 1; // map out-of-range to unknown
|
if ( d >= lookupValues.get(inum).length ) d = 1; // map out-of-range to unknown
|
||||||
ld[inum++] = d;
|
ld[inum++] = d;
|
||||||
|
@ -265,7 +267,7 @@ public final class BExpressionContext
|
||||||
|
|
||||||
public String getCsvDescription( boolean inverseDirection, byte[] ab )
|
public String getCsvDescription( boolean inverseDirection, byte[] ab )
|
||||||
{
|
{
|
||||||
int inverseBitByteIndex = readVarLength ? 0 : 7;
|
int inverseBitByteIndex = meta.readVarLength ? 0 : 7;
|
||||||
int abLen = ab.length;
|
int abLen = ab.length;
|
||||||
byte[] ab_copy = new byte[abLen];
|
byte[] ab_copy = new byte[abLen];
|
||||||
System.arraycopy( ab, 0, ab_copy, 0 , abLen );
|
System.arraycopy( ab, 0, ab_copy, 0 , abLen );
|
||||||
|
@ -275,8 +277,10 @@ public final class BExpressionContext
|
||||||
decode( lookupData, ab_copy );
|
decode( lookupData, ab_copy );
|
||||||
for( int inum = 0; inum < lookupValues.size(); inum++ ) // loop over lookup names
|
for( int inum = 0; inum < lookupValues.size(); inum++ ) // loop over lookup names
|
||||||
{
|
{
|
||||||
BExpressionLookupValue[] va = lookupValues.get(inum);
|
int idx = meta.readVarLength ? (inum+1)%lookupValues.size() : inum; // reversebit at the end..
|
||||||
sb.append( '\t' ).append( va[lookupData[inum]].toString() );
|
|
||||||
|
BExpressionLookupValue[] va = lookupValues.get(idx);
|
||||||
|
sb.append( '\t' ).append( va[lookupData[idx]].toString() );
|
||||||
}
|
}
|
||||||
return sb.toString();
|
return sb.toString();
|
||||||
}
|
}
|
||||||
|
@ -284,9 +288,10 @@ public final class BExpressionContext
|
||||||
public String getCsvHeader()
|
public String getCsvHeader()
|
||||||
{
|
{
|
||||||
StringBuilder sb = new StringBuilder( 200 );
|
StringBuilder sb = new StringBuilder( 200 );
|
||||||
for( String name: lookupNames )
|
for( int inum = 0; inum < lookupNames.size(); inum++ ) // loop over lookup names
|
||||||
{
|
{
|
||||||
sb.append( '\t' ).append( name );
|
int idx = meta.readVarLength ? (inum+1)%lookupValues.size() : inum; // reversebit at the end..
|
||||||
|
sb.append( '\t' ).append( lookupNames.get(idx) );
|
||||||
}
|
}
|
||||||
return sb.toString();
|
return sb.toString();
|
||||||
}
|
}
|
||||||
|
@ -307,42 +312,11 @@ public final class BExpressionContext
|
||||||
return sb.toString();
|
return sb.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void readMetaData( File lookupsFile )
|
private int parsedLines = 0;
|
||||||
|
private boolean fixTagsWritten = false;
|
||||||
|
|
||||||
|
public void parseMetaLine( String line )
|
||||||
{
|
{
|
||||||
try
|
|
||||||
{
|
|
||||||
BufferedReader br = new BufferedReader( new FileReader( lookupsFile ) );
|
|
||||||
|
|
||||||
int parsedLines = 0;
|
|
||||||
boolean ourContext = false;
|
|
||||||
boolean fixTagsWritten = false;
|
|
||||||
for(;;)
|
|
||||||
{
|
|
||||||
String line = br.readLine();
|
|
||||||
if ( line == null ) break;
|
|
||||||
line = line.trim();
|
|
||||||
if ( line.length() == 0 || line.startsWith( "#" ) ) continue;
|
|
||||||
if ( line.startsWith( CONTEXT_TAG ) )
|
|
||||||
{
|
|
||||||
ourContext = line.substring( CONTEXT_TAG.length() ).equals( context );
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if ( line.startsWith( VERSION_TAG ) )
|
|
||||||
{
|
|
||||||
lookupVersion = Short.parseShort( line.substring( VERSION_TAG.length() ) );
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if ( line.startsWith( MINOR_VERSION_TAG ) )
|
|
||||||
{
|
|
||||||
lookupMinorVersion = Short.parseShort( line.substring( MINOR_VERSION_TAG.length() ) );
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if ( line.startsWith( VARLENGTH_TAG ) )
|
|
||||||
{
|
|
||||||
readVarLength = true;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if ( !ourContext ) continue;
|
|
||||||
parsedLines++;
|
parsedLines++;
|
||||||
StringTokenizer tk = new StringTokenizer( line, " " );
|
StringTokenizer tk = new StringTokenizer( line, " " );
|
||||||
String name = tk.nextToken();
|
String name = tk.nextToken();
|
||||||
|
@ -350,7 +324,7 @@ public final class BExpressionContext
|
||||||
int idx = name.indexOf( ';' );
|
int idx = name.indexOf( ';' );
|
||||||
if ( idx >= 0 ) name = name.substring( 0, idx );
|
if ( idx >= 0 ) name = name.substring( 0, idx );
|
||||||
|
|
||||||
if ( readVarLength )
|
if ( meta.readVarLength )
|
||||||
{
|
{
|
||||||
if ( !fixTagsWritten )
|
if ( !fixTagsWritten )
|
||||||
{
|
{
|
||||||
|
@ -358,28 +332,24 @@ public final class BExpressionContext
|
||||||
if ( "way".equals( context ) ) addLookupValue( "reversedirection", "yes", null );
|
if ( "way".equals( context ) ) addLookupValue( "reversedirection", "yes", null );
|
||||||
else if ( "node".equals( context ) ) addLookupValue( "nodeaccessgranted", "yes", null );
|
else if ( "node".equals( context ) ) addLookupValue( "nodeaccessgranted", "yes", null );
|
||||||
}
|
}
|
||||||
if ( "reversedirection".equals( name ) ) continue; // this is hardcoded
|
if ( "reversedirection".equals( name ) ) return; // this is hardcoded
|
||||||
if ( "nodeaccessgranted".equals( name ) ) continue; // this is hardcoded
|
if ( "nodeaccessgranted".equals( name ) ) return; // this is hardcoded
|
||||||
}
|
}
|
||||||
BExpressionLookupValue newValue = addLookupValue( name, value, null );
|
BExpressionLookupValue newValue = addLookupValue( name, value, null );
|
||||||
|
|
||||||
// add aliases
|
// add aliases
|
||||||
while( newValue != null && tk.hasMoreTokens() ) newValue.addAlias( tk.nextToken() );
|
while( newValue != null && tk.hasMoreTokens() ) newValue.addAlias( tk.nextToken() );
|
||||||
}
|
}
|
||||||
br.close();
|
|
||||||
|
public void finishMetaParsing()
|
||||||
|
{
|
||||||
if ( parsedLines == 0 && !"global".equals(context) )
|
if ( parsedLines == 0 && !"global".equals(context) )
|
||||||
{
|
{
|
||||||
throw new IllegalArgumentException( lookupsFile.getAbsolutePath()
|
throw new IllegalArgumentException( "lookup table does not contain data for context " + context + " (old version?)" );
|
||||||
+ " does not contain data for context " + context + " (old version?)" );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// post-process metadata:
|
// post-process metadata:
|
||||||
lookupDataFrozen = true;
|
lookupDataFrozen = true;
|
||||||
}
|
|
||||||
catch( Exception e )
|
|
||||||
{
|
|
||||||
throw new RuntimeException( e );
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void evaluate( int[] lookupData2 )
|
public void evaluate( int[] lookupData2 )
|
||||||
|
@ -400,7 +370,9 @@ public final class BExpressionContext
|
||||||
*/
|
*/
|
||||||
public boolean evaluate( boolean inverseDirection, byte[] ab, BExpressionReceiver receiver )
|
public boolean evaluate( boolean inverseDirection, byte[] ab, BExpressionReceiver receiver )
|
||||||
{
|
{
|
||||||
int inverseBitByteIndex = readVarLength ? 0 : 7;
|
lookupDataValid = false; // this is an assertion for a nasty pifall
|
||||||
|
|
||||||
|
int inverseBitByteIndex = meta.readVarLength ? 0 : 7;
|
||||||
|
|
||||||
int abLen = ab.length;
|
int abLen = ab.length;
|
||||||
boolean equalsCurrent = currentHashBucket >= 0 && abLen == currentByteArray.length;
|
boolean equalsCurrent = currentHashBucket >= 0 && abLen == currentByteArray.length;
|
||||||
|
@ -685,18 +657,12 @@ public final class BExpressionContext
|
||||||
return num == null ? defaultValue : getVariableValue( num.intValue() );
|
return num == null ? defaultValue : getVariableValue( num.intValue() );
|
||||||
}
|
}
|
||||||
|
|
||||||
public float getVariableValue( String name )
|
float getVariableValue( int variableIdx )
|
||||||
{
|
|
||||||
Integer num = variableNumbers.get( name );
|
|
||||||
return num == null ? 0.f : getVariableValue( num.intValue() );
|
|
||||||
}
|
|
||||||
|
|
||||||
public float getVariableValue( int variableIdx )
|
|
||||||
{
|
{
|
||||||
return variableData[variableIdx];
|
return variableData[variableIdx];
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getVariableIdx( String name, boolean create )
|
int getVariableIdx( String name, boolean create )
|
||||||
{
|
{
|
||||||
Integer num = variableNumbers.get( name );
|
Integer num = variableNumbers.get( name );
|
||||||
if ( num == null )
|
if ( num == null )
|
||||||
|
@ -714,12 +680,12 @@ public final class BExpressionContext
|
||||||
return num.intValue();
|
return num.intValue();
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getMinWriteIdx()
|
int getMinWriteIdx()
|
||||||
{
|
{
|
||||||
return minWriteIdx;
|
return minWriteIdx;
|
||||||
}
|
}
|
||||||
|
|
||||||
public float getLookupMatch( int nameIdx, int valueIdx )
|
float getLookupMatch( int nameIdx, int valueIdx )
|
||||||
{
|
{
|
||||||
return lookupData[nameIdx] == valueIdx ? 1.0f : 0.0f;
|
return lookupData[nameIdx] == valueIdx ? 1.0f : 0.0f;
|
||||||
}
|
}
|
||||||
|
@ -730,7 +696,7 @@ public final class BExpressionContext
|
||||||
return num == null ? -1 : num.intValue();
|
return num == null ? -1 : num.intValue();
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getLookupValueIdx( int nameIdx, String value )
|
int getLookupValueIdx( int nameIdx, String value )
|
||||||
{
|
{
|
||||||
BExpressionLookupValue[] values = lookupValues.get( nameIdx );
|
BExpressionLookupValue[] values = lookupValues.get( nameIdx );
|
||||||
for( int i=0; i< values.length; i++ )
|
for( int i=0; i< values.length; i++ )
|
||||||
|
@ -741,7 +707,7 @@ public final class BExpressionContext
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public String parseToken() throws Exception
|
String parseToken() throws Exception
|
||||||
{
|
{
|
||||||
for(;;)
|
for(;;)
|
||||||
{
|
{
|
||||||
|
@ -790,13 +756,13 @@ public final class BExpressionContext
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public float assign( int variableIdx, float value )
|
float assign( int variableIdx, float value )
|
||||||
{
|
{
|
||||||
variableData[variableIdx] = value;
|
variableData[variableIdx] = value;
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void expressionWarning( String message )
|
void expressionWarning( String message )
|
||||||
{
|
{
|
||||||
_arrayBitmap[currentHashBucket] = null; // no caching if warnings
|
_arrayBitmap[currentHashBucket] = null; // no caching if warnings
|
||||||
if ( _receiver != null ) _receiver.expressionWarning( context, message );
|
if ( _receiver != null ) _receiver.expressionWarning( context, message );
|
||||||
|
|
|
@ -0,0 +1,91 @@
|
||||||
|
// context for simple expression
|
||||||
|
// context means:
|
||||||
|
// - the local variables
|
||||||
|
// - the local variable names
|
||||||
|
// - the lookup-input variables
|
||||||
|
|
||||||
|
package btools.expressions;
|
||||||
|
|
||||||
|
import java.io.BufferedReader;
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.FileReader;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.StringTokenizer;
|
||||||
|
import java.util.TreeMap;
|
||||||
|
|
||||||
|
import btools.util.BitCoderContext;
|
||||||
|
import btools.util.Crc32;
|
||||||
|
|
||||||
|
|
||||||
|
public final class BExpressionMetaData
|
||||||
|
{
|
||||||
|
private static final String CONTEXT_TAG = "---context:";
|
||||||
|
private static final String VERSION_TAG = "---lookupversion:";
|
||||||
|
private static final String MINOR_VERSION_TAG = "---minorversion:";
|
||||||
|
private static final String VARLENGTH_TAG = "---readvarlength";
|
||||||
|
|
||||||
|
public short lookupVersion = -1;
|
||||||
|
public short lookupMinorVersion = -1;
|
||||||
|
public boolean readVarLength = false;
|
||||||
|
|
||||||
|
private HashMap<String,BExpressionContext> listeners = new HashMap<String,BExpressionContext>();
|
||||||
|
|
||||||
|
public void registerListener( String context, BExpressionContext ctx )
|
||||||
|
{
|
||||||
|
listeners.put( context, ctx );
|
||||||
|
}
|
||||||
|
|
||||||
|
public void readMetaData( File lookupsFile )
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
BufferedReader br = new BufferedReader( new FileReader( lookupsFile ) );
|
||||||
|
|
||||||
|
BExpressionContext ctx = null;
|
||||||
|
|
||||||
|
for(;;)
|
||||||
|
{
|
||||||
|
String line = br.readLine();
|
||||||
|
if ( line == null ) break;
|
||||||
|
line = line.trim();
|
||||||
|
if ( line.length() == 0 || line.startsWith( "#" ) ) continue;
|
||||||
|
if ( line.startsWith( CONTEXT_TAG ) )
|
||||||
|
{
|
||||||
|
ctx = listeners.get( line.substring( CONTEXT_TAG.length() ) );
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if ( line.startsWith( VERSION_TAG ) )
|
||||||
|
{
|
||||||
|
lookupVersion = Short.parseShort( line.substring( VERSION_TAG.length() ) );
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if ( line.startsWith( MINOR_VERSION_TAG ) )
|
||||||
|
{
|
||||||
|
lookupMinorVersion = Short.parseShort( line.substring( MINOR_VERSION_TAG.length() ) );
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if ( line.startsWith( VARLENGTH_TAG ) )
|
||||||
|
{
|
||||||
|
readVarLength = true;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if ( ctx != null ) ctx.parseMetaLine( line );
|
||||||
|
}
|
||||||
|
br.close();
|
||||||
|
|
||||||
|
for( BExpressionContext c : listeners.values() )
|
||||||
|
{
|
||||||
|
c.finishMetaParsing();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
catch( Exception e )
|
||||||
|
{
|
||||||
|
throw new RuntimeException( e );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -18,8 +18,9 @@ public class EncodeDecodeTest
|
||||||
File lookupFile = new File( profileDir, "lookups.dat" );
|
File lookupFile = new File( profileDir, "lookups.dat" );
|
||||||
|
|
||||||
// read lookup.dat + trekking.brf
|
// read lookup.dat + trekking.brf
|
||||||
BExpressionContext expctxWay = new BExpressionContext("way");
|
BExpressionMetaData meta = new BExpressionMetaData();
|
||||||
expctxWay.readMetaData( lookupFile );
|
BExpressionContext expctxWay = new BExpressionContext("way", 4096, meta );
|
||||||
|
meta.readMetaData( lookupFile );
|
||||||
expctxWay.parseFile( new File( profileDir, "trekking.brf" ), "global" );
|
expctxWay.parseFile( new File( profileDir, "trekking.brf" ), "global" );
|
||||||
|
|
||||||
String[] tags = { "highway=residential", "oneway=yes", "reversedirection=yes" };
|
String[] tags = { "highway=residential", "oneway=yes", "reversedirection=yes" };
|
||||||
|
|
|
@ -15,9 +15,11 @@ import java.io.FileOutputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
|
|
||||||
|
import btools.util.DiffCoderDataOutputStream;
|
||||||
|
|
||||||
public abstract class MapCreatorBase implements WayListener, NodeListener, RelationListener
|
public abstract class MapCreatorBase implements WayListener, NodeListener, RelationListener
|
||||||
{
|
{
|
||||||
private DataOutputStream[] tileOutStreams;
|
private DiffCoderDataOutputStream[] tileOutStreams;
|
||||||
protected File outTileDir;
|
protected File outTileDir;
|
||||||
|
|
||||||
protected HashMap<String,String> tags;
|
protected HashMap<String,String> tags;
|
||||||
|
@ -102,16 +104,16 @@ public abstract class MapCreatorBase implements WayListener, NodeListener, Relat
|
||||||
return new DataInputStream( new BufferedInputStream ( new FileInputStream( inFile ) ) );
|
return new DataInputStream( new BufferedInputStream ( new FileInputStream( inFile ) ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
protected DataOutputStream createOutStream( File outFile ) throws IOException
|
protected DiffCoderDataOutputStream createOutStream( File outFile ) throws IOException
|
||||||
{
|
{
|
||||||
return new DataOutputStream( new BufferedOutputStream( new FileOutputStream( outFile ) ) );
|
return new DiffCoderDataOutputStream( new BufferedOutputStream( new FileOutputStream( outFile ) ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
protected DataOutputStream getOutStreamForTile( int tileIndex ) throws Exception
|
protected DiffCoderDataOutputStream getOutStreamForTile( int tileIndex ) throws Exception
|
||||||
{
|
{
|
||||||
if ( tileOutStreams == null )
|
if ( tileOutStreams == null )
|
||||||
{
|
{
|
||||||
tileOutStreams = new DataOutputStream[64];
|
tileOutStreams = new DiffCoderDataOutputStream[64];
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( tileOutStreams[tileIndex] == null )
|
if ( tileOutStreams[tileIndex] == null )
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
package btools.mapcreator;
|
package btools.mapcreator;
|
||||||
|
|
||||||
import java.io.DataInputStream;
|
import btools.util.DiffCoderDataInputStream;
|
||||||
import java.io.DataOutputStream;
|
import btools.util.DiffCoderDataOutputStream;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Container for node data on the preprocessor level
|
* Container for node data on the preprocessor level
|
||||||
|
@ -23,21 +23,21 @@ public class NodeData extends MapCreatorBase
|
||||||
ilon = (int)( ( lon + 180. )*1000000. + 0.5);
|
ilon = (int)( ( lon + 180. )*1000000. + 0.5);
|
||||||
}
|
}
|
||||||
|
|
||||||
public NodeData( DataInputStream dis ) throws Exception
|
public NodeData( DiffCoderDataInputStream dis ) throws Exception
|
||||||
{
|
{
|
||||||
nid = readId( dis );
|
nid = dis.readDiffed( 0 );
|
||||||
ilon = dis.readInt();
|
ilon = (int)dis.readDiffed( 1 );
|
||||||
ilat = dis.readInt();
|
ilat = (int)dis.readDiffed( 2 );
|
||||||
int mode = dis.readByte();
|
int mode = dis.readByte();
|
||||||
if ( ( mode & 1 ) != 0 ) { int dlen = dis.readByte(); description = new byte[dlen]; dis.readFully( description ); }
|
if ( ( mode & 1 ) != 0 ) { int dlen = dis.readByte(); description = new byte[dlen]; dis.readFully( description ); }
|
||||||
if ( ( mode & 2 ) != 0 ) selev = dis.readShort();
|
if ( ( mode & 2 ) != 0 ) selev = dis.readShort();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void writeTo( DataOutputStream dos ) throws Exception
|
public void writeTo( DiffCoderDataOutputStream dos ) throws Exception
|
||||||
{
|
{
|
||||||
writeId( dos, nid );
|
dos.writeDiffed( nid, 0 );
|
||||||
dos.writeInt( ilon );
|
dos.writeDiffed( ilon, 1 );
|
||||||
dos.writeInt( ilat );
|
dos.writeDiffed( ilat, 2 );
|
||||||
int mode = ( description == null ? 0 : 1 ) | ( selev == Short.MIN_VALUE ? 0 : 2 );
|
int mode = ( description == null ? 0 : 1 ) | ( selev == Short.MIN_VALUE ? 0 : 2 );
|
||||||
dos.writeByte( (byte)mode );
|
dos.writeByte( (byte)mode );
|
||||||
if ( ( mode & 1 ) != 0 ) { dos.writeByte( description.length ); dos.write( description ); }
|
if ( ( mode & 1 ) != 0 ) { dos.writeByte( description.length ); dos.write( description ); }
|
||||||
|
|
|
@ -1,11 +1,11 @@
|
||||||
package btools.mapcreator;
|
package btools.mapcreator;
|
||||||
|
|
||||||
import java.io.BufferedOutputStream;
|
import java.io.BufferedOutputStream;
|
||||||
import java.io.DataOutputStream;
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.FileOutputStream;
|
import java.io.FileOutputStream;
|
||||||
|
|
||||||
import btools.util.DenseLongMap;
|
import btools.util.DenseLongMap;
|
||||||
|
import btools.util.DiffCoderDataOutputStream;
|
||||||
import btools.util.TinyDenseLongMap;
|
import btools.util.TinyDenseLongMap;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -17,7 +17,7 @@ import btools.util.TinyDenseLongMap;
|
||||||
*/
|
*/
|
||||||
public class NodeFilter extends MapCreatorBase
|
public class NodeFilter extends MapCreatorBase
|
||||||
{
|
{
|
||||||
private DataOutputStream nodesOutStream;
|
private DiffCoderDataOutputStream nodesOutStream;
|
||||||
private File nodeTilesOut;
|
private File nodeTilesOut;
|
||||||
protected DenseLongMap nodebitmap;
|
protected DenseLongMap nodebitmap;
|
||||||
|
|
||||||
|
@ -61,7 +61,7 @@ public class NodeFilter extends MapCreatorBase
|
||||||
String filename = nodefile.getName();
|
String filename = nodefile.getName();
|
||||||
filename = filename.substring( 0, filename.length() - 3 ) + "tlf";
|
filename = filename.substring( 0, filename.length() - 3 ) + "tlf";
|
||||||
File outfile = new File( nodeTilesOut, filename );
|
File outfile = new File( nodeTilesOut, filename );
|
||||||
nodesOutStream = new DataOutputStream( new BufferedOutputStream ( new FileOutputStream( outfile ) ) );
|
nodesOutStream = new DiffCoderDataOutputStream( new BufferedOutputStream ( new FileOutputStream( outfile ) ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -1,11 +1,12 @@
|
||||||
package btools.mapcreator;
|
package btools.mapcreator;
|
||||||
|
|
||||||
import java.io.BufferedInputStream;
|
import java.io.BufferedInputStream;
|
||||||
import java.io.DataInputStream;
|
|
||||||
import java.io.EOFException;
|
import java.io.EOFException;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.FileInputStream;
|
import java.io.FileInputStream;
|
||||||
|
|
||||||
|
import btools.util.DiffCoderDataInputStream;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Iterate over a singe nodefile or a directory
|
* Iterate over a singe nodefile or a directory
|
||||||
* of nodetiles and feed the nodes to the callback listener
|
* of nodetiles and feed the nodes to the callback listener
|
||||||
|
@ -48,7 +49,7 @@ public class NodeIterator extends MapCreatorBase
|
||||||
|
|
||||||
listener.nodeFileStart( nodefile );
|
listener.nodeFileStart( nodefile );
|
||||||
|
|
||||||
DataInputStream di = new DataInputStream( new BufferedInputStream ( new FileInputStream( nodefile ) ) );
|
DiffCoderDataInputStream di = new DiffCoderDataInputStream( new BufferedInputStream ( new FileInputStream( nodefile ) ) );
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
for(;;)
|
for(;;)
|
||||||
|
|
|
@ -13,6 +13,7 @@ import java.io.File;
|
||||||
import java.io.FileOutputStream;
|
import java.io.FileOutputStream;
|
||||||
|
|
||||||
import btools.expressions.BExpressionContext;
|
import btools.expressions.BExpressionContext;
|
||||||
|
import btools.expressions.BExpressionMetaData;
|
||||||
|
|
||||||
public class OsmCutter extends MapCreatorBase
|
public class OsmCutter extends MapCreatorBase
|
||||||
{
|
{
|
||||||
|
@ -47,7 +48,7 @@ public class OsmCutter extends MapCreatorBase
|
||||||
private BExpressionContext _expctxNode;
|
private BExpressionContext _expctxNode;
|
||||||
|
|
||||||
private BExpressionContext _expctxWayStat;
|
private BExpressionContext _expctxWayStat;
|
||||||
private BExpressionContext _expctxNodeStat;
|
// private BExpressionContext _expctxNodeStat;
|
||||||
|
|
||||||
public void process (File lookupFile, File outTileDir, File wayFile, File relFile, File mapFile) throws Exception
|
public void process (File lookupFile, File outTileDir, File wayFile, File relFile, File mapFile) throws Exception
|
||||||
{
|
{
|
||||||
|
@ -56,13 +57,13 @@ public class OsmCutter extends MapCreatorBase
|
||||||
throw new IllegalArgumentException( "lookup-file: " + lookupFile + " does not exist" );
|
throw new IllegalArgumentException( "lookup-file: " + lookupFile + " does not exist" );
|
||||||
}
|
}
|
||||||
|
|
||||||
_expctxWay = new BExpressionContext("way");
|
BExpressionMetaData meta = new BExpressionMetaData();
|
||||||
_expctxWay.readMetaData( lookupFile );
|
|
||||||
// _expctxWayStat = new BExpressionContext("way");
|
|
||||||
|
|
||||||
_expctxNode = new BExpressionContext("node");
|
_expctxWay = new BExpressionContext("way", meta );
|
||||||
_expctxNode.readMetaData( lookupFile );
|
_expctxNode = new BExpressionContext("node", meta );
|
||||||
// _expctxNodeStat = new BExpressionContext("node");
|
meta.readMetaData( lookupFile );
|
||||||
|
// _expctxWayStat = new BExpressionContext("way", null );
|
||||||
|
// _expctxNodeStat = new BExpressionContext("node", null );
|
||||||
|
|
||||||
this.outTileDir = outTileDir;
|
this.outTileDir = outTileDir;
|
||||||
if ( !outTileDir.isDirectory() ) throw new RuntimeException( "out tile directory " + outTileDir + " does not exist" );
|
if ( !outTileDir.isDirectory() ) throw new RuntimeException( "out tile directory " + outTileDir + " does not exist" );
|
||||||
|
@ -122,8 +123,7 @@ public class OsmCutter extends MapCreatorBase
|
||||||
int tileIndex = getTileIndex( n.ilon, n.ilat );
|
int tileIndex = getTileIndex( n.ilon, n.ilat );
|
||||||
if ( tileIndex >= 0 )
|
if ( tileIndex >= 0 )
|
||||||
{
|
{
|
||||||
DataOutputStream dos = getOutStreamForTile( tileIndex );
|
n.writeTo( getOutStreamForTile( tileIndex ) );
|
||||||
n.writeTo( dos );
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -9,10 +9,14 @@ import java.io.ByteArrayOutputStream;
|
||||||
import java.io.DataOutputStream;
|
import java.io.DataOutputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
|
||||||
|
import sun.security.pkcs.SigningCertificateInfo;
|
||||||
|
|
||||||
|
import btools.util.ByteDataWriter;
|
||||||
|
|
||||||
public class OsmNodeP implements Comparable<OsmNodeP>
|
public class OsmNodeP implements Comparable<OsmNodeP>
|
||||||
{
|
{
|
||||||
public static final int EXTERNAL_BITMASK = 0x80;
|
public static final int SIGNLON_BITMASK = 0x80;
|
||||||
public static final int VARIABLEDESC_BITMASK = 0x40;
|
public static final int SIGNLAT_BITMASK = 0x40;
|
||||||
public static final int TRANSFERNODE_BITMASK = 0x20;
|
public static final int TRANSFERNODE_BITMASK = 0x20;
|
||||||
public static final int WRITEDESC_BITMASK = 0x10;
|
public static final int WRITEDESC_BITMASK = 0x10;
|
||||||
public static final int SKIPDETAILS_BITMASK = 0x08;
|
public static final int SKIPDETAILS_BITMASK = 0x08;
|
||||||
|
@ -42,10 +46,12 @@ public class OsmNodeP implements Comparable<OsmNodeP>
|
||||||
|
|
||||||
public boolean isBorder = false;
|
public boolean isBorder = false;
|
||||||
|
|
||||||
public final static int BRIDGE_AND_BIT = 1;
|
public final static int NO_BRIDGE_BIT = 1;
|
||||||
public final static int TUNNEL_AND_BIT = 2;
|
public final static int NO_TUNNEL_BIT = 2;
|
||||||
public byte wayAndBits = -1; // use for bridge/tunnel logic
|
public final static int LCN_BIT = 4;
|
||||||
|
public final static int CR_BIT = 8;
|
||||||
|
|
||||||
|
public byte wayBits = 0;
|
||||||
|
|
||||||
// interface OsmPos
|
// interface OsmPos
|
||||||
public int getILat()
|
public int getILat()
|
||||||
|
@ -61,7 +67,7 @@ public class OsmNodeP implements Comparable<OsmNodeP>
|
||||||
public short getSElev()
|
public short getSElev()
|
||||||
{
|
{
|
||||||
// if all bridge or all tunnel, elevation=no-data
|
// if all bridge or all tunnel, elevation=no-data
|
||||||
return (wayAndBits & ( BRIDGE_AND_BIT | TUNNEL_AND_BIT ) ) == 0 ? selev : Short.MIN_VALUE;
|
return ( wayBits & NO_BRIDGE_BIT ) == 0 || ( wayBits & NO_TUNNEL_BIT ) == 0 ? Short.MIN_VALUE : selev;
|
||||||
}
|
}
|
||||||
|
|
||||||
public double getElev()
|
public double getElev()
|
||||||
|
@ -82,22 +88,23 @@ public class OsmNodeP implements Comparable<OsmNodeP>
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void writeNodeData( DataOutputStream os, boolean writeVarLength ) throws IOException
|
public void writeNodeData( ByteDataWriter os, boolean writeVarLength, byte[] abBuf ) throws IOException
|
||||||
{
|
{
|
||||||
int lonIdx = ilon/62500;
|
int lonIdx = ilon/62500;
|
||||||
int latIdx = ilat/62500;
|
int latIdx = ilat/62500;
|
||||||
|
|
||||||
// buffer the body to first calc size
|
// buffer the body to first calc size
|
||||||
ByteArrayOutputStream bos = new ByteArrayOutputStream( );
|
ByteDataWriter os2 = new ByteDataWriter( abBuf );
|
||||||
DataOutputStream os2 = new DataOutputStream( bos );
|
|
||||||
|
|
||||||
os2.writeShort( getSElev() );
|
os2.writeShort( getSElev() );
|
||||||
|
|
||||||
// hack: write node-desc as link tag (copy cycleway-bits)
|
// hack: write node-desc as link tag (copy cycleway-bits)
|
||||||
byte[] nodeDescription = getNodeDecsription();
|
byte[] nodeDescription = getNodeDecsription();
|
||||||
|
|
||||||
for( OsmLinkP link0 = firstlink; link0 != null; link0 = link0.next )
|
for( OsmLinkP link0 = firstlink; link0 != null; link0 = link0.next )
|
||||||
{
|
{
|
||||||
|
int ilonref = ilon;
|
||||||
|
int ilatref = ilat;
|
||||||
|
|
||||||
OsmLinkP link = link0;
|
OsmLinkP link = link0;
|
||||||
OsmNodeP origin = this;
|
OsmNodeP origin = this;
|
||||||
int skipDetailBit = link0.counterLinkWritten() ? SKIPDETAILS_BITMASK : 0;
|
int skipDetailBit = link0.counterLinkWritten() ? SKIPDETAILS_BITMASK : 0;
|
||||||
|
@ -160,32 +167,24 @@ public class OsmNodeP implements Comparable<OsmNodeP>
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
int targetLonIdx = target.ilon/62500;
|
|
||||||
int targetLatIdx = target.ilat/62500;
|
|
||||||
|
|
||||||
int bm = tranferbit | writedescbit | nodedescbit | skipDetailBit;
|
int bm = tranferbit | writedescbit | nodedescbit | skipDetailBit;
|
||||||
if ( writeVarLength ) bm |= VARIABLEDESC_BITMASK;
|
int dlon = target.ilon - ilonref;
|
||||||
|
int dlat = target.ilat - ilatref;
|
||||||
|
ilonref = target.ilon;
|
||||||
|
ilatref = target.ilat;
|
||||||
|
if ( dlon < 0 ) { bm |= SIGNLON_BITMASK; dlon = - dlon; }
|
||||||
|
if ( dlat < 0 ) { bm |= SIGNLAT_BITMASK; dlat = - dlat; }
|
||||||
|
os2.writeByte( bm );
|
||||||
|
|
||||||
|
int blon = os2.writeVarLengthUnsigned( dlon );
|
||||||
|
int blat = os2.writeVarLengthUnsigned( dlat );
|
||||||
|
|
||||||
if ( targetLonIdx == lonIdx && targetLatIdx == latIdx )
|
|
||||||
{
|
|
||||||
// reduced position for internal target
|
|
||||||
os2.writeByte( bm );
|
|
||||||
os2.writeShort( (short)(target.ilon - lonIdx*62500 - 31250) );
|
|
||||||
os2.writeShort( (short)(target.ilat - latIdx*62500 - 31250) );
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// full position for external target
|
|
||||||
os2.writeByte( bm | EXTERNAL_BITMASK );
|
|
||||||
os2.writeInt( target.ilon );
|
|
||||||
os2.writeInt( target.ilat );
|
|
||||||
}
|
|
||||||
if ( writedescbit != 0 )
|
if ( writedescbit != 0 )
|
||||||
{
|
{
|
||||||
// write the way description, code direction into the first bit
|
// write the way description, code direction into the first bit
|
||||||
int len = lastDescription.length;
|
if ( writeVarLength ) os2.writeByte( lastDescription.length );
|
||||||
if ( writeVarLength ) os2.writeByte( len );
|
os2.write( lastDescription );
|
||||||
os2.write( lastDescription, 0, len );
|
|
||||||
}
|
}
|
||||||
if ( nodedescbit != 0 )
|
if ( nodedescbit != 0 )
|
||||||
{
|
{
|
||||||
|
@ -199,7 +198,7 @@ public class OsmNodeP implements Comparable<OsmNodeP>
|
||||||
target.markLinkWritten( origin );
|
target.markLinkWritten( origin );
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
os2.writeShort( target.getSElev() );
|
os2.writeVarLengthSigned( target.getSElev() -getSElev() );
|
||||||
// next link is the one (of two), does does'nt point back
|
// next link is the one (of two), does does'nt point back
|
||||||
for( link = target.firstlink; link != null; link = link.next )
|
for( link = target.firstlink; link != null; link = link.next )
|
||||||
{
|
{
|
||||||
|
@ -211,12 +210,15 @@ public class OsmNodeP implements Comparable<OsmNodeP>
|
||||||
}
|
}
|
||||||
|
|
||||||
// calculate the body size
|
// calculate the body size
|
||||||
int bodySize = bos.size();
|
int bodySize = os2.size();
|
||||||
|
|
||||||
|
os.ensureCapacity( bodySize + 8 );
|
||||||
|
|
||||||
os.writeShort( (short)(ilon - lonIdx*62500 - 31250) );
|
os.writeShort( (short)(ilon - lonIdx*62500 - 31250) );
|
||||||
os.writeShort( (short)(ilat - latIdx*62500 - 31250) );
|
os.writeShort( (short)(ilat - latIdx*62500 - 31250) );
|
||||||
os.writeInt( bodySize );
|
|
||||||
bos.writeTo( os );
|
os.writeVarLengthUnsigned( bodySize );
|
||||||
|
os.write( abBuf, 0, bodySize );
|
||||||
}
|
}
|
||||||
|
|
||||||
public String toString2()
|
public String toString2()
|
||||||
|
|
|
@ -10,8 +10,6 @@ public class OsmNodePT extends OsmNodeP
|
||||||
{
|
{
|
||||||
public byte[] descriptionBits;
|
public byte[] descriptionBits;
|
||||||
|
|
||||||
public byte wayOrBits = 0; // used to propagate bike networks to nodes
|
|
||||||
|
|
||||||
public OsmNodePT()
|
public OsmNodePT()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
@ -25,7 +23,6 @@ public class OsmNodePT extends OsmNodeP
|
||||||
public final byte[] getNodeDecsription()
|
public final byte[] getNodeDecsription()
|
||||||
{
|
{
|
||||||
return descriptionBits;
|
return descriptionBits;
|
||||||
// return descriptionBits | (long)( (wayOrBits & 6) >> 1 ); TODO !!!!!!!!!!1
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -7,6 +7,7 @@ import java.io.File;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
|
|
||||||
import btools.util.CompactLongSet;
|
import btools.util.CompactLongSet;
|
||||||
|
import btools.util.DiffCoderDataOutputStream;
|
||||||
import btools.util.FrozenLongSet;
|
import btools.util.FrozenLongSet;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -21,8 +22,8 @@ import btools.util.FrozenLongSet;
|
||||||
*/
|
*/
|
||||||
public class PosUnifier extends MapCreatorBase
|
public class PosUnifier extends MapCreatorBase
|
||||||
{
|
{
|
||||||
private DataOutputStream nodesOutStream;
|
private DiffCoderDataOutputStream nodesOutStream;
|
||||||
private DataOutputStream borderNodesOut;
|
private DiffCoderDataOutputStream borderNodesOut;
|
||||||
private File nodeTilesOut;
|
private File nodeTilesOut;
|
||||||
private CompactLongSet positionSet;
|
private CompactLongSet positionSet;
|
||||||
|
|
||||||
|
|
|
@ -7,6 +7,7 @@ import java.io.File;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
|
|
||||||
import btools.expressions.BExpressionContext;
|
import btools.expressions.BExpressionContext;
|
||||||
|
import btools.expressions.BExpressionMetaData;
|
||||||
import btools.util.CompactLongSet;
|
import btools.util.CompactLongSet;
|
||||||
import btools.util.FrozenLongSet;
|
import btools.util.FrozenLongSet;
|
||||||
|
|
||||||
|
@ -29,7 +30,7 @@ public class RelationMerger extends MapCreatorBase
|
||||||
|
|
||||||
public static void main(String[] args) throws Exception
|
public static void main(String[] args) throws Exception
|
||||||
{
|
{
|
||||||
System.out.println("*** RelationMerger: merge relation bits into ways" );
|
System.out.println("*** RelationMerger: merge relations into ways" );
|
||||||
if (args.length != 6)
|
if (args.length != 6)
|
||||||
{
|
{
|
||||||
System.out.println("usage: java RelationMerger <way-file-in> <way-file-out> <relation-file> <lookup-file> <report-profile> <check-profile>" );
|
System.out.println("usage: java RelationMerger <way-file-in> <way-file-out> <relation-file> <lookup-file> <report-profile> <check-profile>" );
|
||||||
|
@ -42,11 +43,15 @@ public class RelationMerger extends MapCreatorBase
|
||||||
public void process( File wayFileIn, File wayFileOut, File relationFileIn, File lookupFile, File reportProfile, File checkProfile ) throws Exception
|
public void process( File wayFileIn, File wayFileOut, File relationFileIn, File lookupFile, File reportProfile, File checkProfile ) throws Exception
|
||||||
{
|
{
|
||||||
// read lookup + profile for relation access-check
|
// read lookup + profile for relation access-check
|
||||||
expctxReport = new BExpressionContext("way");
|
BExpressionMetaData metaReport = new BExpressionMetaData();
|
||||||
expctxReport.readMetaData( lookupFile );
|
expctxReport = new BExpressionContext("way", metaReport );
|
||||||
|
metaReport.readMetaData( lookupFile );
|
||||||
|
|
||||||
|
BExpressionMetaData metaCheck = new BExpressionMetaData();
|
||||||
|
expctxCheck = new BExpressionContext("way", metaCheck );
|
||||||
|
metaCheck.readMetaData( lookupFile );
|
||||||
|
|
||||||
expctxReport.parseFile( reportProfile, "global" );
|
expctxReport.parseFile( reportProfile, "global" );
|
||||||
expctxCheck = new BExpressionContext("way");
|
|
||||||
expctxCheck.readMetaData( lookupFile );
|
|
||||||
expctxCheck.parseFile( checkProfile, "global" );
|
expctxCheck.parseFile( checkProfile, "global" );
|
||||||
// expctxStat = new BExpressionContext("way");
|
// expctxStat = new BExpressionContext("way");
|
||||||
|
|
||||||
|
@ -63,6 +68,7 @@ public class RelationMerger extends MapCreatorBase
|
||||||
String network = dis.readUTF();
|
String network = dis.readUTF();
|
||||||
|
|
||||||
String tagname = "route_" + route + "_" + network;
|
String tagname = "route_" + route + "_" + network;
|
||||||
|
|
||||||
CompactLongSet routeset = null;
|
CompactLongSet routeset = null;
|
||||||
if ( expctxCheck.getLookupNameIdx(tagname) >= 0 )
|
if ( expctxCheck.getLookupNameIdx(tagname) >= 0 )
|
||||||
{
|
{
|
||||||
|
@ -127,6 +133,7 @@ public class RelationMerger extends MapCreatorBase
|
||||||
|
|
||||||
if ( ok )
|
if ( ok )
|
||||||
{
|
{
|
||||||
|
expctxReport.decode( data.description );
|
||||||
for( String tagname : routesets.keySet() )
|
for( String tagname : routesets.keySet() )
|
||||||
{
|
{
|
||||||
CompactLongSet routeset = routesets.get( tagname );
|
CompactLongSet routeset = routesets.get( tagname );
|
||||||
|
|
|
@ -8,7 +8,9 @@ import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import btools.expressions.BExpressionContext;
|
import btools.expressions.BExpressionContext;
|
||||||
|
import btools.expressions.BExpressionMetaData;
|
||||||
import btools.util.ByteArrayUnifier;
|
import btools.util.ByteArrayUnifier;
|
||||||
|
import btools.util.ByteDataWriter;
|
||||||
import btools.util.CompactLongMap;
|
import btools.util.CompactLongMap;
|
||||||
import btools.util.CompactLongSet;
|
import btools.util.CompactLongSet;
|
||||||
import btools.util.Crc32;
|
import btools.util.Crc32;
|
||||||
|
@ -45,6 +47,7 @@ public class WayLinker extends MapCreatorBase
|
||||||
private long creationTimeStamp;
|
private long creationTimeStamp;
|
||||||
|
|
||||||
private BExpressionContext expctxWay;
|
private BExpressionContext expctxWay;
|
||||||
|
private BExpressionContext expctxNode;
|
||||||
|
|
||||||
private ByteArrayUnifier abUnifier;
|
private ByteArrayUnifier abUnifier;
|
||||||
|
|
||||||
|
@ -77,13 +80,19 @@ public class WayLinker extends MapCreatorBase
|
||||||
this.borderFileIn = borderFileIn;
|
this.borderFileIn = borderFileIn;
|
||||||
this.dataTilesSuffix = dataTilesSuffix;
|
this.dataTilesSuffix = dataTilesSuffix;
|
||||||
|
|
||||||
|
BExpressionMetaData meta = new BExpressionMetaData();
|
||||||
|
|
||||||
// read lookup + profile for lookup-version + access-filter
|
// read lookup + profile for lookup-version + access-filter
|
||||||
expctxWay = new BExpressionContext("way");
|
expctxWay = new BExpressionContext("way", meta);
|
||||||
expctxWay.readMetaData( lookupFile );
|
expctxNode = new BExpressionContext("node", meta);
|
||||||
lookupVersion = expctxWay.lookupVersion;
|
meta.readMetaData( lookupFile );
|
||||||
lookupMinorVersion = expctxWay.lookupMinorVersion;
|
|
||||||
writeVarLength = expctxWay.readVarLength;
|
lookupVersion = meta.lookupVersion;
|
||||||
|
lookupMinorVersion = meta.lookupMinorVersion;
|
||||||
|
writeVarLength = meta.readVarLength;
|
||||||
|
|
||||||
expctxWay.parseFile( profileFile, "global" );
|
expctxWay.parseFile( profileFile, "global" );
|
||||||
|
expctxNode.parseFile( profileFile, "global" );
|
||||||
|
|
||||||
creationTimeStamp = System.currentTimeMillis();
|
creationTimeStamp = System.currentTimeMillis();
|
||||||
|
|
||||||
|
@ -158,11 +167,11 @@ public class WayLinker extends MapCreatorBase
|
||||||
ok |= expctxWay.getCostfactor() < 10000.;
|
ok |= expctxWay.getCostfactor() < 10000.;
|
||||||
if ( !ok ) return;
|
if ( !ok ) return;
|
||||||
|
|
||||||
byte bridgeTunnel = 0;
|
byte wayBits = 0;
|
||||||
expctxWay.decode( description );
|
expctxWay.decode( description );
|
||||||
if ( expctxWay.getBooleanLookupValue( "bridge" ) ) bridgeTunnel |= OsmNodeP.BRIDGE_AND_BIT;
|
if ( !expctxWay.getBooleanLookupValue( "bridge" ) ) wayBits |= OsmNodeP.NO_BRIDGE_BIT;
|
||||||
if ( expctxWay.getBooleanLookupValue( "tunnel" ) ) bridgeTunnel |= OsmNodeP.TUNNEL_AND_BIT;
|
if ( !expctxWay.getBooleanLookupValue( "tunnel" ) ) wayBits |= OsmNodeP.NO_TUNNEL_BIT;
|
||||||
|
|
||||||
OsmNodeP n1 = null;
|
OsmNodeP n1 = null;
|
||||||
OsmNodeP n2 = null;
|
OsmNodeP n2 = null;
|
||||||
for (int i=0; i<way.nodes.size(); i++)
|
for (int i=0; i<way.nodes.size(); i++)
|
||||||
|
@ -185,7 +194,7 @@ public class WayLinker extends MapCreatorBase
|
||||||
}
|
}
|
||||||
if ( n2 != null )
|
if ( n2 != null )
|
||||||
{
|
{
|
||||||
n2.wayAndBits &= bridgeTunnel;
|
n2.wayBits |= wayBits;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -195,6 +204,9 @@ public class WayLinker extends MapCreatorBase
|
||||||
{
|
{
|
||||||
nodesMap = null;
|
nodesMap = null;
|
||||||
borderSet = null;
|
borderSet = null;
|
||||||
|
|
||||||
|
byte[] abBuf = new byte[1024*1024];
|
||||||
|
byte[] abBuf2 = new byte[10*1024*1024];
|
||||||
|
|
||||||
int maxLon = minLon + 5000000;
|
int maxLon = minLon + 5000000;
|
||||||
int maxLat = minLat + 5000000;
|
int maxLat = minLat + 5000000;
|
||||||
|
@ -264,17 +276,16 @@ public class WayLinker extends MapCreatorBase
|
||||||
{
|
{
|
||||||
Collections.sort( subList );
|
Collections.sort( subList );
|
||||||
|
|
||||||
ByteArrayOutputStream bos = new ByteArrayOutputStream( );
|
ByteDataWriter dos = new ByteDataWriter( abBuf2 );
|
||||||
DataOutputStream dos = new DataOutputStream( bos );
|
|
||||||
dos.writeInt( subList.size() + 1 ); // reserve 1 dummy node for crc
|
dos.writeInt( subList.size() );
|
||||||
for( int ni=0; ni<subList.size(); ni++ )
|
for( int ni=0; ni<subList.size(); ni++ )
|
||||||
{
|
{
|
||||||
OsmNodeP n = subList.get(ni);
|
OsmNodeP n = subList.get(ni);
|
||||||
n.writeNodeData( dos, writeVarLength );
|
n.writeNodeData( dos, writeVarLength, abBuf );
|
||||||
}
|
}
|
||||||
dos.close();
|
byte[] subBytes = dos.toByteArray();
|
||||||
byte[] subBytes = bos.toByteArray();
|
pos += subBytes.length + 4; // reserve 4 bytes for crc
|
||||||
pos += subBytes.length + 12; // reserve 12 bytes for crc dummy node
|
|
||||||
subByteArrays[si] = subBytes;
|
subByteArrays[si] = subBytes;
|
||||||
}
|
}
|
||||||
posIdx[si] = pos;
|
posIdx[si] = pos;
|
||||||
|
@ -289,9 +300,6 @@ public class WayLinker extends MapCreatorBase
|
||||||
if ( ab != null )
|
if ( ab != null )
|
||||||
{
|
{
|
||||||
os.write( ab );
|
os.write( ab );
|
||||||
os.writeShort( Short.MAX_VALUE ); // write crc as a dummy node for compatibility
|
|
||||||
os.writeShort( Short.MAX_VALUE );
|
|
||||||
os.writeInt( 4 );
|
|
||||||
os.writeInt( Crc32.crc( ab, 0 , ab.length ) );
|
os.writeInt( Crc32.crc( ab, 0 , ab.length ) );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,12 +5,14 @@
|
||||||
*/
|
*/
|
||||||
package btools.mapaccess;
|
package btools.mapaccess;
|
||||||
|
|
||||||
import java.util.*;
|
import java.io.IOException;
|
||||||
import java.io.*;
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import btools.util.ByteDataReader;
|
||||||
import btools.util.Crc32;
|
import btools.util.Crc32;
|
||||||
|
|
||||||
final class MicroCache
|
final class MicroCache extends ByteDataReader
|
||||||
{
|
{
|
||||||
private long[] faid;
|
private long[] faid;
|
||||||
private int[] fapos;
|
private int[] fapos;
|
||||||
|
@ -18,10 +20,10 @@ final class MicroCache
|
||||||
private int delcount = 0;
|
private int delcount = 0;
|
||||||
private int delbytes = 0;
|
private int delbytes = 0;
|
||||||
private int p2size; // next power of 2 of size
|
private int p2size; // next power of 2 of size
|
||||||
|
|
||||||
|
private boolean readVarLength;
|
||||||
|
|
||||||
// the object parsing position and length
|
// the object parsing position and length
|
||||||
private byte[] ab;
|
|
||||||
private int aboffset;
|
|
||||||
private int aboffsetEnd;
|
private int aboffsetEnd;
|
||||||
|
|
||||||
// cache control: a virgin cache can be
|
// cache control: a virgin cache can be
|
||||||
|
@ -29,8 +31,11 @@ final class MicroCache
|
||||||
boolean virgin = true;
|
boolean virgin = true;
|
||||||
boolean ghost = false;
|
boolean ghost = false;
|
||||||
|
|
||||||
public MicroCache( OsmFile segfile, int lonIdx80, int latIdx80, byte[] iobuffer ) throws Exception
|
public MicroCache( OsmFile segfile, int lonIdx80, int latIdx80, byte[] iobuffer, boolean readVarLength ) throws Exception
|
||||||
{
|
{
|
||||||
|
super( null );
|
||||||
|
this.readVarLength = readVarLength;
|
||||||
|
|
||||||
int lonDegree = lonIdx80/80;
|
int lonDegree = lonIdx80/80;
|
||||||
int latDegree = latIdx80/80;
|
int latDegree = latIdx80/80;
|
||||||
|
|
||||||
|
@ -55,20 +60,22 @@ final class MicroCache
|
||||||
}
|
}
|
||||||
aboffset = 0;
|
aboffset = 0;
|
||||||
size = readInt();
|
size = readInt();
|
||||||
|
|
||||||
// get net size
|
// get net size
|
||||||
int nbytes = 0;
|
int nbytes = 0;
|
||||||
for(int i = 0; i<size; i++)
|
for(int i = 0; i<size; i++)
|
||||||
{
|
{
|
||||||
int ilon = readShort();
|
int ilon = readShort();
|
||||||
int ilat = readShort();
|
int ilat = readShort();
|
||||||
int bodySize = readInt();
|
int bodySize = readVarLength ? readVarLengthUnsigned() : readInt();
|
||||||
if ( ilon == Short.MAX_VALUE && ilat == Short.MAX_VALUE )
|
|
||||||
|
// kack for the old format crc
|
||||||
|
if ( !readVarLength && ilon == Short.MAX_VALUE && ilat == Short.MAX_VALUE )
|
||||||
{
|
{
|
||||||
int crc = Crc32.crc( ab, 0, aboffset-8 );
|
int crc = Crc32.crc( ab, 0, aboffset-8 ); // old format crc
|
||||||
if ( crc != readInt() )
|
if ( crc != readInt() )
|
||||||
{
|
{
|
||||||
throw new IOException( "checkum error" );
|
throw new IOException( "checkum-error" );
|
||||||
}
|
}
|
||||||
size = i;
|
size = i;
|
||||||
break;
|
break;
|
||||||
|
@ -77,6 +84,15 @@ final class MicroCache
|
||||||
nbytes += bodySize;
|
nbytes += bodySize;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ( readVarLength ) // new format crc
|
||||||
|
{
|
||||||
|
int crc = Crc32.crc( ab, 0, aboffset );
|
||||||
|
if ( crc != readInt() )
|
||||||
|
{
|
||||||
|
throw new IOException( "checkum error" );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// new array with only net data
|
// new array with only net data
|
||||||
byte[] nab = new byte[nbytes];
|
byte[] nab = new byte[nbytes];
|
||||||
aboffset = 4;
|
aboffset = 4;
|
||||||
|
@ -95,7 +111,7 @@ final class MicroCache
|
||||||
long nodeId = ((long)ilon)<<32 | ilat;
|
long nodeId = ((long)ilon)<<32 | ilat;
|
||||||
|
|
||||||
faid[i] = nodeId;
|
faid[i] = nodeId;
|
||||||
int bodySize = readInt();
|
int bodySize = readVarLength ? readVarLengthUnsigned() : readInt();
|
||||||
fapos[i] = noffset;
|
fapos[i] = noffset;
|
||||||
System.arraycopy( ab, aboffset, nab, noffset, bodySize );
|
System.arraycopy( ab, aboffset, nab, noffset, bodySize );
|
||||||
aboffset += bodySize;
|
aboffset += bodySize;
|
||||||
|
@ -173,7 +189,7 @@ final class MicroCache
|
||||||
long id = node.getIdFromPos();
|
long id = node.getIdFromPos();
|
||||||
if ( getAndClear( id ) )
|
if ( getAndClear( id ) )
|
||||||
{
|
{
|
||||||
node.parseNodeBody( this, nodesMap, dc );
|
node.parseNodeBody( this, nodesMap, dc, readVarLength );
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( doCollect && delcount > size / 2 ) // garbage collection
|
if ( doCollect && delcount > size / 2 ) // garbage collection
|
||||||
|
@ -252,53 +268,6 @@ final class MicroCache
|
||||||
return positions;
|
return positions;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int readInt()
|
|
||||||
{
|
|
||||||
int i3 = ab[aboffset++]& 0xff;
|
|
||||||
int i2 = ab[aboffset++]& 0xff;
|
|
||||||
int i1 = ab[aboffset++]& 0xff;
|
|
||||||
int i0 = ab[aboffset++]& 0xff;
|
|
||||||
return (i3 << 24) + (i2 << 16) + (i1 << 8) + i0;
|
|
||||||
}
|
|
||||||
|
|
||||||
public long readLong()
|
|
||||||
{
|
|
||||||
long i7 = ab[aboffset++]& 0xff;
|
|
||||||
long i6 = ab[aboffset++]& 0xff;
|
|
||||||
long i5 = ab[aboffset++]& 0xff;
|
|
||||||
long i4 = ab[aboffset++]& 0xff;
|
|
||||||
long i3 = ab[aboffset++]& 0xff;
|
|
||||||
long i2 = ab[aboffset++]& 0xff;
|
|
||||||
long i1 = ab[aboffset++]& 0xff;
|
|
||||||
long i0 = ab[aboffset++]& 0xff;
|
|
||||||
return (i7 << 56) + (i6 << 48) + (i5 << 40) + (i4 << 32) + (i3 << 24) + (i2 << 16) + (i1 << 8) + i0;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean readBoolean()
|
|
||||||
{
|
|
||||||
int i0 = ab[aboffset++]& 0xff;
|
|
||||||
return i0 != 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
public byte readByte()
|
|
||||||
{
|
|
||||||
int i0 = ab[aboffset++] & 0xff;
|
|
||||||
return (byte)(i0);
|
|
||||||
}
|
|
||||||
|
|
||||||
public short readShort()
|
|
||||||
{
|
|
||||||
int i1 = ab[aboffset++] & 0xff;
|
|
||||||
int i0 = ab[aboffset++] & 0xff;
|
|
||||||
return (short)( (i1 << 8) | i0);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void readFully( byte[] ta )
|
|
||||||
{
|
|
||||||
System.arraycopy( ab, aboffset, ta, 0, ta.length );
|
|
||||||
aboffset += ta.length;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean hasMoreData()
|
public boolean hasMoreData()
|
||||||
{
|
{
|
||||||
return aboffset < aboffsetEnd;
|
return aboffset < aboffsetEnd;
|
||||||
|
|
|
@ -17,6 +17,7 @@ public final class NodesCache
|
||||||
private OsmNodesMap nodesMap;
|
private OsmNodesMap nodesMap;
|
||||||
private int lookupVersion;
|
private int lookupVersion;
|
||||||
private int lookupMinorVersion;
|
private int lookupMinorVersion;
|
||||||
|
private boolean readVarLength;
|
||||||
private boolean carMode;
|
private boolean carMode;
|
||||||
private String currentFileName;
|
private String currentFileName;
|
||||||
|
|
||||||
|
@ -33,12 +34,13 @@ public final class NodesCache
|
||||||
private long cacheSum = 0;
|
private long cacheSum = 0;
|
||||||
private boolean garbageCollectionEnabled = false;
|
private boolean garbageCollectionEnabled = false;
|
||||||
|
|
||||||
public NodesCache( String segmentDir, OsmNodesMap nodesMap, int lookupVersion, int lookupMinorVersion, boolean carMode, NodesCache oldCache )
|
public NodesCache( String segmentDir, OsmNodesMap nodesMap, int lookupVersion, int minorVersion, boolean varLen, boolean carMode, NodesCache oldCache )
|
||||||
{
|
{
|
||||||
this.segmentDir = segmentDir;
|
this.segmentDir = segmentDir;
|
||||||
this.nodesMap = nodesMap;
|
this.nodesMap = nodesMap;
|
||||||
this.lookupVersion = lookupVersion;
|
this.lookupVersion = lookupVersion;
|
||||||
this.lookupMinorVersion = lookupMinorVersion;
|
this.lookupMinorVersion = minorVersion;
|
||||||
|
this.readVarLength = varLen;
|
||||||
this.carMode = carMode;
|
this.carMode = carMode;
|
||||||
|
|
||||||
if ( oldCache != null )
|
if ( oldCache != null )
|
||||||
|
@ -145,7 +147,7 @@ public final class NodesCache
|
||||||
|
|
||||||
checkEnableCacheCleaning();
|
checkEnableCacheCleaning();
|
||||||
|
|
||||||
segment = new MicroCache( osmf, lonIdx80, latIdx80, iobuffer );
|
segment = new MicroCache( osmf, lonIdx80, latIdx80, iobuffer, readVarLength );
|
||||||
cacheSum += segment.getDataSize();
|
cacheSum += segment.getDataSize();
|
||||||
osmf.microCaches[subIdx] = segment;
|
osmf.microCaches[subIdx] = segment;
|
||||||
segmentList.add( segment );
|
segmentList.add( segment );
|
||||||
|
|
|
@ -7,6 +7,8 @@ package btools.mapaccess;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.RandomAccessFile;
|
import java.io.RandomAccessFile;
|
||||||
|
|
||||||
|
import btools.util.ByteDataReader;
|
||||||
import btools.util.Crc32;
|
import btools.util.Crc32;
|
||||||
|
|
||||||
final class OsmFile
|
final class OsmFile
|
||||||
|
|
|
@ -11,8 +11,9 @@ import btools.util.ByteArrayUnifier;
|
||||||
|
|
||||||
public class OsmNode implements OsmPos
|
public class OsmNode implements OsmPos
|
||||||
{
|
{
|
||||||
public static final int EXTERNAL_BITMASK = 0x80;
|
public static final int EXTERNAL_BITMASK = 0x80; // old semantic
|
||||||
public static final int VARIABLEDESC_BITMASK = 0x40;
|
public static final int SIGNLON_BITMASK = 0x80;
|
||||||
|
public static final int SIGNLAT_BITMASK = 0x40;
|
||||||
public static final int TRANSFERNODE_BITMASK = 0x20;
|
public static final int TRANSFERNODE_BITMASK = 0x20;
|
||||||
public static final int WRITEDESC_BITMASK = 0x10;
|
public static final int WRITEDESC_BITMASK = 0x10;
|
||||||
public static final int SKIPDETAILS_BITMASK = 0x08;
|
public static final int SKIPDETAILS_BITMASK = 0x08;
|
||||||
|
@ -111,10 +112,10 @@ public class OsmNode implements OsmPos
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public void parseNodeBody( MicroCache is, OsmNodesMap hollowNodes, DistanceChecker dc )
|
public void parseNodeBody( MicroCache is, OsmNodesMap hollowNodes, DistanceChecker dc, boolean readVarLength )
|
||||||
{
|
{
|
||||||
ByteArrayUnifier abUnifier = hollowNodes.getByteArrayUnifier();
|
ByteArrayUnifier abUnifier = hollowNodes.getByteArrayUnifier();
|
||||||
|
|
||||||
selev = is.readShort();
|
selev = is.readShort();
|
||||||
|
|
||||||
OsmLink lastlink = null;
|
OsmLink lastlink = null;
|
||||||
|
@ -124,6 +125,9 @@ public class OsmNode implements OsmPos
|
||||||
|
|
||||||
while( is.hasMoreData() )
|
while( is.hasMoreData() )
|
||||||
{
|
{
|
||||||
|
int ilonref = ilon;
|
||||||
|
int ilatref = ilat;
|
||||||
|
|
||||||
OsmLink link = new OsmLink();
|
OsmLink link = new OsmLink();
|
||||||
OsmTransferNode firstTransferNode = null;
|
OsmTransferNode firstTransferNode = null;
|
||||||
OsmTransferNode lastTransferNode = null;
|
OsmTransferNode lastTransferNode = null;
|
||||||
|
@ -133,31 +137,45 @@ public class OsmNode implements OsmPos
|
||||||
for(;;)
|
for(;;)
|
||||||
{
|
{
|
||||||
int bitField = is.readByte();
|
int bitField = is.readByte();
|
||||||
if ( (bitField & EXTERNAL_BITMASK) != 0 )
|
// System.out.println( "parseNodeBody: var=" + readVarLength + " bitField=" + bitField );
|
||||||
|
if ( readVarLength )
|
||||||
{
|
{
|
||||||
// full position for external target
|
int dlon = is.readVarLengthUnsigned();
|
||||||
linklon = is.readInt();
|
int dlat = is.readVarLengthUnsigned();
|
||||||
linklat = is.readInt();
|
if ( (bitField & SIGNLON_BITMASK) != 0 ) { dlon = -dlon;}
|
||||||
|
if ( (bitField & SIGNLAT_BITMASK) != 0 ) { dlat = -dlat;}
|
||||||
|
linklon = ilonref + dlon;
|
||||||
|
linklat = ilatref + dlat;
|
||||||
|
ilonref = linklon;
|
||||||
|
ilatref = linklat;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// reduced position for internal target
|
if ( (bitField & EXTERNAL_BITMASK) != 0 )
|
||||||
linklon = is.readShort();
|
{
|
||||||
linklat = is.readShort();
|
// full position for external target
|
||||||
linklon += lonIdx*62500 + 31250;
|
linklon = is.readInt();
|
||||||
linklat += latIdx*62500 + 31250;
|
linklat = is.readInt();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// reduced position for internal target
|
||||||
|
linklon = is.readShort();
|
||||||
|
linklat = is.readShort();
|
||||||
|
linklon += lonIdx*62500 + 31250;
|
||||||
|
linklat += latIdx*62500 + 31250;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
// read variable length or old 8 byte fixed, and ensure that 8 bytes is only fixed
|
// read variable length or old 8 byte fixed, and ensure that 8 bytes is only fixed
|
||||||
boolean readFix8 = (bitField & VARIABLEDESC_BITMASK ) == 0; // old, fix length format
|
|
||||||
if ( (bitField & WRITEDESC_BITMASK ) != 0 )
|
if ( (bitField & WRITEDESC_BITMASK ) != 0 )
|
||||||
{
|
{
|
||||||
byte[] ab = new byte[readFix8 ? 8 : is.readByte()];
|
byte[] ab = new byte[readVarLength ? is.readByte() : 8 ];
|
||||||
is.readFully( ab );
|
is.readFully( ab );
|
||||||
description = abUnifier.unify( ab );
|
description = abUnifier.unify( ab );
|
||||||
}
|
}
|
||||||
if ( (bitField & NODEDESC_BITMASK ) != 0 )
|
if ( (bitField & NODEDESC_BITMASK ) != 0 )
|
||||||
{
|
{
|
||||||
byte[] ab = new byte[readFix8 ? 8 : is.readByte()];
|
byte[] ab = new byte[readVarLength ? is.readByte() : 8 ];
|
||||||
is.readFully( ab );
|
is.readFully( ab );
|
||||||
nodeDescription = abUnifier.unify( ab );
|
nodeDescription = abUnifier.unify( ab );
|
||||||
}
|
}
|
||||||
|
@ -185,7 +203,7 @@ public class OsmNode implements OsmPos
|
||||||
trans.ilon = linklon;
|
trans.ilon = linklon;
|
||||||
trans.ilat = linklat;
|
trans.ilat = linklat;
|
||||||
trans.descriptionBitmap = description;
|
trans.descriptionBitmap = description;
|
||||||
trans.selev = is.readShort();
|
trans.selev = readVarLength ? (short)(selev + is.readVarLengthSigned()) : is.readShort();
|
||||||
if ( lastTransferNode == null )
|
if ( lastTransferNode == null )
|
||||||
{
|
{
|
||||||
firstTransferNode = trans;
|
firstTransferNode = trans;
|
||||||
|
|
|
@ -5,6 +5,9 @@
|
||||||
*/
|
*/
|
||||||
package btools.mapaccess;
|
package btools.mapaccess;
|
||||||
|
|
||||||
|
import btools.util.ByteDataReader;
|
||||||
|
import btools.util.ByteDataWriter;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public final class OsmTransferNode
|
public final class OsmTransferNode
|
||||||
|
|
|
@ -6,6 +6,8 @@
|
||||||
package btools.mapaccess;
|
package btools.mapaccess;
|
||||||
|
|
||||||
import java.io.*;
|
import java.io.*;
|
||||||
|
|
||||||
|
import btools.util.ByteDataReader;
|
||||||
import btools.util.Crc32;
|
import btools.util.Crc32;
|
||||||
|
|
||||||
final public class PhysicalFile
|
final public class PhysicalFile
|
||||||
|
@ -37,7 +39,7 @@ final public class PhysicalFile
|
||||||
if ( osmf.microCaches != null )
|
if ( osmf.microCaches != null )
|
||||||
for( int lonIdx80=0; lonIdx80<80; lonIdx80++ )
|
for( int lonIdx80=0; lonIdx80<80; lonIdx80++ )
|
||||||
for( int latIdx80=0; latIdx80<80; latIdx80++ )
|
for( int latIdx80=0; latIdx80<80; latIdx80++ )
|
||||||
new MicroCache( osmf, lonIdx80, latIdx80, iobuffer );
|
new MicroCache( osmf, lonIdx80, latIdx80, iobuffer, true ); // TODO: readVarLength ?
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch( IllegalArgumentException iae )
|
catch( IllegalArgumentException iae )
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
|
||||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
android:versionCode="2"
|
android:versionCode="3"
|
||||||
android:versionName="0.9.9" package="btools.routingapp">
|
android:versionName="1.0.1" package="btools.routingapp">
|
||||||
<application android:icon="@drawable/icon" android:label="@string/app_name">
|
<application android:icon="@drawable/icon" android:label="@string/app_name">
|
||||||
<activity android:name=".BRouterActivity"
|
<activity android:name=".BRouterActivity"
|
||||||
android:label="@string/app_name"
|
android:label="@string/app_name"
|
||||||
|
|
Binary file not shown.
|
@ -152,7 +152,7 @@ public class BInstallerView extends View
|
||||||
private void startDownload( int tileIndex, boolean isCd5 )
|
private void startDownload( int tileIndex, boolean isCd5 )
|
||||||
{
|
{
|
||||||
String namebase = baseNameForTile( tileIndex );
|
String namebase = baseNameForTile( tileIndex );
|
||||||
String baseurl = "http://h2096617.stratoserver.net/brouter/segments2/";
|
String baseurl = "http://brouter.de/brouter/segments3/";
|
||||||
currentDownloadFile = namebase + (isCd5 ? ".cd5" : ".rd5" );
|
currentDownloadFile = namebase + (isCd5 ? ".cd5" : ".rd5" );
|
||||||
String url = baseurl + (isCd5 ? "carsubset/" : "" ) + currentDownloadFile;
|
String url = baseurl + (isCd5 ? "carsubset/" : "" ) + currentDownloadFile;
|
||||||
isDownloading = true;
|
isDownloading = true;
|
||||||
|
@ -584,7 +584,7 @@ float tx, ty;
|
||||||
// download the file
|
// download the file
|
||||||
input = connection.getInputStream();
|
input = connection.getInputStream();
|
||||||
|
|
||||||
int slidx = surl.lastIndexOf( "segments2/" );
|
int slidx = surl.lastIndexOf( "segments3/" );
|
||||||
fname = baseDir + "/brouter/segments2/" + surl.substring( slidx+10 );
|
fname = baseDir + "/brouter/segments2/" + surl.substring( slidx+10 );
|
||||||
tmp_file = new File( fname + "_tmp" );
|
tmp_file = new File( fname + "_tmp" );
|
||||||
if ( new File( fname ).exists() ) return "internal error: file exists: " + fname;
|
if ( new File( fname ).exists() ) return "internal error: file exists: " + fname;
|
||||||
|
|
|
@ -30,6 +30,7 @@ import android.util.DisplayMetrics;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.widget.Toast;
|
import android.widget.Toast;
|
||||||
import btools.expressions.BExpressionContext;
|
import btools.expressions.BExpressionContext;
|
||||||
|
import btools.expressions.BExpressionMetaData;
|
||||||
import btools.mapaccess.OsmNode;
|
import btools.mapaccess.OsmNode;
|
||||||
import btools.router.OsmNodeNamed;
|
import btools.router.OsmNodeNamed;
|
||||||
import btools.router.OsmTrack;
|
import btools.router.OsmTrack;
|
||||||
|
@ -668,13 +669,14 @@ private long startTime = 0L;
|
||||||
boolean[] modesChecked = new boolean[6];
|
boolean[] modesChecked = new boolean[6];
|
||||||
|
|
||||||
// parse global section of profile for mode preselection
|
// parse global section of profile for mode preselection
|
||||||
BExpressionContext expctxGlobal = new BExpressionContext( "global" );
|
BExpressionMetaData meta = new BExpressionMetaData();
|
||||||
expctxGlobal.readMetaData( new File( profileDir, "lookups.dat" ) );
|
BExpressionContext expctxGlobal = new BExpressionContext( "global", meta );
|
||||||
|
meta.readMetaData( new File( profileDir, "lookups.dat" ) );
|
||||||
expctxGlobal.parseFile( new File( profilePath ), null );
|
expctxGlobal.parseFile( new File( profilePath ), null );
|
||||||
expctxGlobal.evaluate( new int[0] );
|
expctxGlobal.evaluate( new int[0] );
|
||||||
boolean isFoot = 0.f != expctxGlobal.getVariableValue( "validForFoot" );
|
boolean isFoot = 0.f != expctxGlobal.getVariableValue( "validForFoot", 0.f );
|
||||||
boolean isBike = 0.f != expctxGlobal.getVariableValue( "validForBikes" );
|
boolean isBike = 0.f != expctxGlobal.getVariableValue( "validForBikes", 0.f );
|
||||||
boolean isCar = 0.f != expctxGlobal.getVariableValue( "validForCars" );
|
boolean isCar = 0.f != expctxGlobal.getVariableValue( "validForCars", 0.f );
|
||||||
|
|
||||||
if ( isFoot || isBike || isCar )
|
if ( isFoot || isBike || isCar )
|
||||||
{
|
{
|
||||||
|
|
|
@ -19,7 +19,7 @@ package btools.util;
|
||||||
// 001 -> 3 + following 2-bit word ( 3..6 )
|
// 001 -> 3 + following 2-bit word ( 3..6 )
|
||||||
// 0001 -> 7 + following 3-bit word ( 7..14 ) etc.
|
// 0001 -> 7 + following 3-bit word ( 7..14 ) etc.
|
||||||
|
|
||||||
public void encodeDistance( int value )
|
public void encodeVarBits( int value )
|
||||||
{
|
{
|
||||||
int range = 0;
|
int range = 0;
|
||||||
while ( value > range )
|
while ( value > range )
|
||||||
|
@ -33,7 +33,7 @@ package btools.util;
|
||||||
}
|
}
|
||||||
|
|
||||||
// twin to encodeDistance
|
// twin to encodeDistance
|
||||||
public int decodeDistance()
|
public int decodeVarBits()
|
||||||
{
|
{
|
||||||
int range = 0;
|
int range = 0;
|
||||||
int value = 0;
|
int value = 0;
|
||||||
|
|
|
@ -9,7 +9,11 @@ public final class ByteArrayUnifier
|
||||||
public ByteArrayUnifier( int size, boolean validateImmutability )
|
public ByteArrayUnifier( int size, boolean validateImmutability )
|
||||||
{
|
{
|
||||||
this.size = size;
|
this.size = size;
|
||||||
byteArrayCache = new byte[size][];
|
|
||||||
|
if ( !Boolean.getBoolean( "disableByteArrayUnifification" ) )
|
||||||
|
{
|
||||||
|
byteArrayCache = new byte[size][];
|
||||||
|
}
|
||||||
if ( validateImmutability ) crcCrosscheck = new int[size];
|
if ( validateImmutability ) crcCrosscheck = new int[size];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -22,6 +26,8 @@ public final class ByteArrayUnifier
|
||||||
*/
|
*/
|
||||||
public byte[] unify( byte[] ab )
|
public byte[] unify( byte[] ab )
|
||||||
{
|
{
|
||||||
|
if ( byteArrayCache == null ) return ab;
|
||||||
|
|
||||||
int n = ab.length;
|
int n = ab.length;
|
||||||
int crc = Crc32.crc( ab, 0, n );
|
int crc = Crc32.crc( ab, 0, n );
|
||||||
int idx = (crc & 0xfffffff) % size;
|
int idx = (crc & 0xfffffff) % size;
|
||||||
|
|
|
@ -1,75 +1,95 @@
|
||||||
/**
|
/**
|
||||||
* fast data-reading from a byte-array
|
* fast data-reading from a byte-array
|
||||||
*
|
*
|
||||||
* @author ab
|
* @author ab
|
||||||
*/
|
*/
|
||||||
package btools.mapaccess;
|
package btools.util;
|
||||||
|
|
||||||
|
|
||||||
final class ByteDataReader
|
public class ByteDataReader
|
||||||
{
|
{
|
||||||
private byte[] ab;
|
protected byte[] ab;
|
||||||
private int aboffset;
|
protected int aboffset;
|
||||||
|
|
||||||
public ByteDataReader( byte[] byteArray )
|
public ByteDataReader( byte[] byteArray )
|
||||||
{
|
{
|
||||||
ab = byteArray;
|
ab = byteArray;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int readInt()
|
public final int readInt()
|
||||||
{
|
{
|
||||||
int i3 = ab[aboffset++]& 0xff;
|
int i3 = ab[aboffset++]& 0xff;
|
||||||
int i2 = ab[aboffset++]& 0xff;
|
int i2 = ab[aboffset++]& 0xff;
|
||||||
int i1 = ab[aboffset++]& 0xff;
|
int i1 = ab[aboffset++]& 0xff;
|
||||||
int i0 = ab[aboffset++]& 0xff;
|
int i0 = ab[aboffset++]& 0xff;
|
||||||
return (i3 << 24) + (i2 << 16) + (i1 << 8) + i0;
|
return (i3 << 24) + (i2 << 16) + (i1 << 8) + i0;
|
||||||
}
|
}
|
||||||
|
|
||||||
public long readLong()
|
public final long readLong()
|
||||||
{
|
{
|
||||||
long i7 = ab[aboffset++]& 0xff;
|
long i7 = ab[aboffset++]& 0xff;
|
||||||
long i6 = ab[aboffset++]& 0xff;
|
long i6 = ab[aboffset++]& 0xff;
|
||||||
long i5 = ab[aboffset++]& 0xff;
|
long i5 = ab[aboffset++]& 0xff;
|
||||||
long i4 = ab[aboffset++]& 0xff;
|
long i4 = ab[aboffset++]& 0xff;
|
||||||
long i3 = ab[aboffset++]& 0xff;
|
long i3 = ab[aboffset++]& 0xff;
|
||||||
long i2 = ab[aboffset++]& 0xff;
|
long i2 = ab[aboffset++]& 0xff;
|
||||||
long i1 = ab[aboffset++]& 0xff;
|
long i1 = ab[aboffset++]& 0xff;
|
||||||
long i0 = ab[aboffset++]& 0xff;
|
long i0 = ab[aboffset++]& 0xff;
|
||||||
return (i7 << 56) + (i6 << 48) + (i5 << 40) + (i4 << 32) + (i3 << 24) + (i2 << 16) + (i1 << 8) + i0;
|
return (i7 << 56) + (i6 << 48) + (i5 << 40) + (i4 << 32) + (i3 << 24) + (i2 << 16) + (i1 << 8) + i0;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean readBoolean()
|
public final boolean readBoolean()
|
||||||
{
|
{
|
||||||
int i0 = ab[aboffset++]& 0xff;
|
int i0 = ab[aboffset++]& 0xff;
|
||||||
return i0 != 0;
|
return i0 != 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
public byte readByte()
|
public final byte readByte()
|
||||||
{
|
{
|
||||||
int i0 = ab[aboffset++] & 0xff;
|
int i0 = ab[aboffset++] & 0xff;
|
||||||
return (byte)(i0);
|
return (byte)(i0);
|
||||||
}
|
}
|
||||||
|
|
||||||
public short readShort()
|
public final short readShort()
|
||||||
{
|
{
|
||||||
int i1 = ab[aboffset++] & 0xff;
|
int i1 = ab[aboffset++] & 0xff;
|
||||||
int i0 = ab[aboffset++] & 0xff;
|
int i0 = ab[aboffset++] & 0xff;
|
||||||
return (short)( (i1 << 8) | i0);
|
return (short)( (i1 << 8) | i0);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void readFully( byte[] ta )
|
public final int readVarLengthSigned()
|
||||||
{
|
{
|
||||||
System.arraycopy( ab, aboffset, ta, 0, ta.length );
|
int v = readVarLengthUnsigned();
|
||||||
aboffset += ta.length;
|
return ( v & 1 ) == 0 ? v >> 1 : -(v >> 1 );
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
public final int readVarLengthUnsigned()
|
||||||
public String toString()
|
{
|
||||||
{
|
int v = 0;
|
||||||
StringBuilder sb = new StringBuilder( "[" );
|
int shift = 0;
|
||||||
for( int i=0; i<ab.length; i++ ) sb.append( i == 0 ? " " : ", " ).append( Integer.toString( ab[i] ) );
|
for(;;)
|
||||||
sb.append( " ]" );
|
{
|
||||||
return sb.toString();
|
int i7 = ab[aboffset++] & 0xff;
|
||||||
}
|
v |= (( i7 & 0x7f ) << shift);
|
||||||
|
if ( ( i7 & 0x80 ) == 0 ) break;
|
||||||
}
|
shift += 7;
|
||||||
|
}
|
||||||
|
return v;
|
||||||
|
}
|
||||||
|
|
||||||
|
public final void readFully( byte[] ta )
|
||||||
|
{
|
||||||
|
System.arraycopy( ab, aboffset, ta, 0, ta.length );
|
||||||
|
aboffset += ta.length;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString()
|
||||||
|
{
|
||||||
|
StringBuilder sb = new StringBuilder( "[" );
|
||||||
|
for( int i=0; i<ab.length; i++ ) sb.append( i == 0 ? " " : ", " ).append( Integer.toString( ab[i] ) );
|
||||||
|
sb.append( " ]" );
|
||||||
|
return sb.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -1,69 +1,111 @@
|
||||||
/**
|
/**
|
||||||
* fast data-reading from a byte-array
|
* fast data-writing to a byte-array
|
||||||
*
|
*
|
||||||
* @author ab
|
* @author ab
|
||||||
*/
|
*/
|
||||||
package btools.mapaccess;
|
package btools.util;
|
||||||
|
|
||||||
|
|
||||||
final class ByteDataWriter
|
public final class ByteDataWriter
|
||||||
{
|
{
|
||||||
private byte[] ab;
|
private byte[] ab;
|
||||||
private int aboffset;
|
private int aboffset;
|
||||||
|
|
||||||
public ByteDataWriter( byte[] byteArray )
|
public ByteDataWriter( byte[] byteArray )
|
||||||
{
|
{
|
||||||
ab = byteArray;
|
ab = byteArray;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void writeInt( int v )
|
public void writeInt( int v )
|
||||||
{
|
{
|
||||||
ab[aboffset++] = (byte)( (v >> 24) & 0xff );
|
ab[aboffset++] = (byte)( (v >> 24) & 0xff );
|
||||||
ab[aboffset++] = (byte)( (v >> 16) & 0xff );
|
ab[aboffset++] = (byte)( (v >> 16) & 0xff );
|
||||||
ab[aboffset++] = (byte)( (v >> 8) & 0xff );
|
ab[aboffset++] = (byte)( (v >> 8) & 0xff );
|
||||||
ab[aboffset++] = (byte)( (v ) & 0xff );
|
ab[aboffset++] = (byte)( (v ) & 0xff );
|
||||||
}
|
}
|
||||||
|
|
||||||
public void writeLong( long v )
|
public void writeLong( long v )
|
||||||
{
|
{
|
||||||
ab[aboffset++] = (byte)( (v >> 56) & 0xff );
|
ab[aboffset++] = (byte)( (v >> 56) & 0xff );
|
||||||
ab[aboffset++] = (byte)( (v >> 48) & 0xff );
|
ab[aboffset++] = (byte)( (v >> 48) & 0xff );
|
||||||
ab[aboffset++] = (byte)( (v >> 40) & 0xff );
|
ab[aboffset++] = (byte)( (v >> 40) & 0xff );
|
||||||
ab[aboffset++] = (byte)( (v >> 32) & 0xff );
|
ab[aboffset++] = (byte)( (v >> 32) & 0xff );
|
||||||
ab[aboffset++] = (byte)( (v >> 24) & 0xff );
|
ab[aboffset++] = (byte)( (v >> 24) & 0xff );
|
||||||
ab[aboffset++] = (byte)( (v >> 16) & 0xff );
|
ab[aboffset++] = (byte)( (v >> 16) & 0xff );
|
||||||
ab[aboffset++] = (byte)( (v >> 8) & 0xff );
|
ab[aboffset++] = (byte)( (v >> 8) & 0xff );
|
||||||
ab[aboffset++] = (byte)( (v ) & 0xff );
|
ab[aboffset++] = (byte)( (v ) & 0xff );
|
||||||
}
|
}
|
||||||
|
|
||||||
public void writeBoolean( boolean v)
|
public void writeBoolean( boolean v)
|
||||||
{
|
{
|
||||||
ab[aboffset++] = (byte)( v ? 1 : 0 );
|
ab[aboffset++] = (byte)( v ? 1 : 0 );
|
||||||
}
|
}
|
||||||
|
|
||||||
public void writeByte( int v )
|
public void writeByte( int v )
|
||||||
{
|
{
|
||||||
ab[aboffset++] = (byte)( (v ) & 0xff );
|
ab[aboffset++] = (byte)( (v ) & 0xff );
|
||||||
}
|
}
|
||||||
|
|
||||||
public void writeShort( int v )
|
public void writeShort( int v )
|
||||||
{
|
{
|
||||||
ab[aboffset++] = (byte)( (v >> 8) & 0xff );
|
ab[aboffset++] = (byte)( (v >> 8) & 0xff );
|
||||||
ab[aboffset++] = (byte)( (v ) & 0xff );
|
ab[aboffset++] = (byte)( (v ) & 0xff );
|
||||||
}
|
}
|
||||||
|
|
||||||
public void write( byte[] sa )
|
public void write( byte[] sa )
|
||||||
{
|
{
|
||||||
System.arraycopy( sa, 0, ab, aboffset, sa.length );
|
System.arraycopy( sa, 0, ab, aboffset, sa.length );
|
||||||
aboffset += sa.length;
|
aboffset += sa.length;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
public void write( byte[] sa, int offset, int len )
|
||||||
public String toString()
|
{
|
||||||
{
|
System.arraycopy( sa, offset, ab, aboffset, len );
|
||||||
StringBuilder sb = new StringBuilder( "[" );
|
aboffset += len;
|
||||||
for( int i=0; i<ab.length; i++ ) sb.append( i == 0 ? " " : ", " ).append( Integer.toString( ab[i] ) );
|
}
|
||||||
sb.append( " ]" );
|
|
||||||
return sb.toString();
|
public void ensureCapacity( int len )
|
||||||
}
|
{
|
||||||
|
// TODO
|
||||||
|
}
|
||||||
|
|
||||||
|
public byte[] toByteArray()
|
||||||
|
{
|
||||||
|
byte[] c = new byte[aboffset];
|
||||||
|
System.arraycopy( ab, 0, c, 0, aboffset );
|
||||||
|
return c;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int writeVarLengthSigned( int v )
|
||||||
|
{
|
||||||
|
return writeVarLengthUnsigned( v < 0 ? ( (-v) << 1 ) | 1 : v << 1 );
|
||||||
|
}
|
||||||
|
|
||||||
|
public int writeVarLengthUnsigned( int v )
|
||||||
|
{
|
||||||
|
int start = aboffset;
|
||||||
|
do
|
||||||
|
{
|
||||||
|
int i7 = v & 0x7f;
|
||||||
|
v >>= 7;
|
||||||
|
if ( v != 0 ) i7 |= 0x80;
|
||||||
|
ab[aboffset++] = (byte)( i7 & 0xff );
|
||||||
|
}
|
||||||
|
while( v != 0 );
|
||||||
|
return aboffset - start;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int size()
|
||||||
|
{
|
||||||
|
return aboffset;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString()
|
||||||
|
{
|
||||||
|
StringBuilder sb = new StringBuilder( "[" );
|
||||||
|
for( int i=0; i<ab.length; i++ ) sb.append( i == 0 ? " " : ", " ).append( Integer.toString( ab[i] ) );
|
||||||
|
sb.append( " ]" );
|
||||||
|
return sb.toString();
|
||||||
|
}
|
||||||
}
|
}
|
|
@ -22,7 +22,8 @@ public class Crc32
|
||||||
public static int crc( byte[] ab, int offset, int len )
|
public static int crc( byte[] ab, int offset, int len )
|
||||||
{
|
{
|
||||||
int crc = 0xFFFFFFFF;
|
int crc = 0xFFFFFFFF;
|
||||||
for( int j=offset; j<len; j++ )
|
int end = offset + len;
|
||||||
|
for( int j=offset; j<end; j++ )
|
||||||
{
|
{
|
||||||
crc = (crc >>> 8) ^ crctable[(crc ^ ab[j]) & 0xff];
|
crc = (crc >>> 8) ^ crctable[(crc ^ ab[j]) & 0xff];
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,49 @@
|
||||||
|
/**
|
||||||
|
* DataInputStream extended by varlength diff coding
|
||||||
|
*
|
||||||
|
* @author ab
|
||||||
|
*/
|
||||||
|
package btools.util;
|
||||||
|
|
||||||
|
import java.io.DataInputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
|
||||||
|
|
||||||
|
public final class DiffCoderDataInputStream extends DataInputStream
|
||||||
|
{
|
||||||
|
private long[] lastValues = new long[10];
|
||||||
|
|
||||||
|
public DiffCoderDataInputStream( InputStream is )
|
||||||
|
{
|
||||||
|
super( is );
|
||||||
|
}
|
||||||
|
|
||||||
|
public long readDiffed( int idx ) throws IOException
|
||||||
|
{
|
||||||
|
long d = readSigned();
|
||||||
|
long v = lastValues[idx] + d;
|
||||||
|
lastValues[idx] = v;
|
||||||
|
return v;
|
||||||
|
}
|
||||||
|
|
||||||
|
public long readSigned() throws IOException
|
||||||
|
{
|
||||||
|
long v = readUnsigned();
|
||||||
|
return ( v & 1 ) == 0 ? v >> 1 : -(v >> 1 );
|
||||||
|
}
|
||||||
|
|
||||||
|
public long readUnsigned() throws IOException
|
||||||
|
{
|
||||||
|
long v = 0;
|
||||||
|
int shift = 0;
|
||||||
|
for(;;)
|
||||||
|
{
|
||||||
|
long i7 = readByte() & 0xff;
|
||||||
|
v |= (( i7 & 0x7f ) << shift);
|
||||||
|
if ( ( i7 & 0x80 ) == 0 ) break;
|
||||||
|
shift += 7;
|
||||||
|
}
|
||||||
|
return v;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,45 @@
|
||||||
|
/**
|
||||||
|
* DataOutputStream extended by varlength diff coding
|
||||||
|
*
|
||||||
|
* @author ab
|
||||||
|
*/
|
||||||
|
package btools.util;
|
||||||
|
|
||||||
|
import java.io.DataOutputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.OutputStream;
|
||||||
|
|
||||||
|
|
||||||
|
public final class DiffCoderDataOutputStream extends DataOutputStream
|
||||||
|
{
|
||||||
|
private long[] lastValues = new long[10];
|
||||||
|
|
||||||
|
public DiffCoderDataOutputStream( OutputStream os )
|
||||||
|
{
|
||||||
|
super( os );
|
||||||
|
}
|
||||||
|
|
||||||
|
public void writeDiffed( long v, int idx ) throws IOException
|
||||||
|
{
|
||||||
|
long d = v - lastValues[idx];
|
||||||
|
lastValues[idx] = v;
|
||||||
|
writeSigned( d );
|
||||||
|
}
|
||||||
|
|
||||||
|
public void writeSigned( long v ) throws IOException
|
||||||
|
{
|
||||||
|
writeUnsigned( v < 0 ? ( (-v) << 1 ) | 1 : v << 1 );
|
||||||
|
}
|
||||||
|
|
||||||
|
public void writeUnsigned( long v ) throws IOException
|
||||||
|
{
|
||||||
|
do
|
||||||
|
{
|
||||||
|
long i7 = v & 0x7f;
|
||||||
|
v >>= 7;
|
||||||
|
if ( v != 0 ) i7 |= 0x80;
|
||||||
|
writeByte( (byte)( i7 & 0xff ) );
|
||||||
|
}
|
||||||
|
while( v != 0 );
|
||||||
|
}
|
||||||
|
}
|
|
@ -9,19 +9,19 @@ import org.junit.Test;
|
||||||
public class BitCoderContextTest
|
public class BitCoderContextTest
|
||||||
{
|
{
|
||||||
@Test
|
@Test
|
||||||
public void distanceEncodeDecodeTest()
|
public void varBitsEncodeDecodeTest()
|
||||||
{
|
{
|
||||||
byte[] ab = new byte[4000];
|
byte[] ab = new byte[4000];
|
||||||
BitCoderContext ctx = new BitCoderContext( ab );
|
BitCoderContext ctx = new BitCoderContext( ab );
|
||||||
for( int i=0; i<1000; i++ )
|
for( int i=0; i<1000; i++ )
|
||||||
{
|
{
|
||||||
ctx.encodeDistance( i );
|
ctx.encodeVarBits( i );
|
||||||
}
|
}
|
||||||
ctx = new BitCoderContext( ab );
|
ctx = new BitCoderContext( ab );
|
||||||
|
|
||||||
for( int i=0; i<1000; i++ )
|
for( int i=0; i<1000; i++ )
|
||||||
{
|
{
|
||||||
int value = ctx.decodeDistance();
|
int value = ctx.decodeVarBits();
|
||||||
Assert.assertTrue( "distance value mismatch", value == i );
|
Assert.assertTrue( "distance value mismatch", value == i );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
28
brouter-util/src/test/java/btools/util/ByteDataIOTest.java
Normal file
28
brouter-util/src/test/java/btools/util/ByteDataIOTest.java
Normal file
|
@ -0,0 +1,28 @@
|
||||||
|
package btools.util;
|
||||||
|
|
||||||
|
import java.util.Random;
|
||||||
|
import java.util.HashSet;
|
||||||
|
|
||||||
|
import org.junit.Assert;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
public class ByteDataIOTest
|
||||||
|
{
|
||||||
|
@Test
|
||||||
|
public void varLengthEncodeDecodeTest()
|
||||||
|
{
|
||||||
|
byte[] ab = new byte[4000];
|
||||||
|
ByteDataWriter w = new ByteDataWriter( ab );
|
||||||
|
for( int i=0; i<1000; i++ )
|
||||||
|
{
|
||||||
|
w.writeVarLengthUnsigned( i );
|
||||||
|
}
|
||||||
|
ByteDataReader r = new ByteDataReader( ab );
|
||||||
|
|
||||||
|
for( int i=0; i<1000; i++ )
|
||||||
|
{
|
||||||
|
int value = r.readVarLengthUnsigned();
|
||||||
|
Assert.assertTrue( "value mismatch", value == i );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in a new issue