removed some old stuff, added profiler, minor performance tuning
This commit is contained in:
parent
42e9ddbdd1
commit
f70dd3c3ac
22 changed files with 234 additions and 802 deletions
|
@ -1,99 +0,0 @@
|
|||
package btools.codec;
|
||||
|
||||
import btools.util.ByteDataWriter;
|
||||
|
||||
/**
|
||||
* MicroCache1 is the old data format as of brouter 1.1 that does not allow to
|
||||
* filter out unaccessable nodes at the beginning of the cache pipeline
|
||||
*
|
||||
* Kept for backward compatibility
|
||||
*/
|
||||
public final class MicroCache1 extends MicroCache
|
||||
{
|
||||
private int lonIdxBase;
|
||||
private int latIdxBase;
|
||||
|
||||
public MicroCache1( int size, byte[] databuffer, int lonIdx80, int latIdx80 ) throws Exception
|
||||
{
|
||||
super( databuffer ); // sets ab=databuffer, aboffset=0
|
||||
faid = new int[size];
|
||||
fapos = new int[size];
|
||||
this.size = 0;
|
||||
lonIdxBase = ( lonIdx80 / 5 ) * 62500 + 31250;
|
||||
latIdxBase = ( latIdx80 / 5 ) * 62500 + 31250;
|
||||
}
|
||||
|
||||
public MicroCache1( byte[] databuffer, int lonIdx80, int latIdx80 ) throws Exception
|
||||
{
|
||||
super( databuffer ); // sets ab=databuffer, aboffset=0
|
||||
lonIdxBase = ( lonIdx80 / 5 ) * 62500 + 31250;
|
||||
latIdxBase = ( latIdx80 / 5 ) * 62500 + 31250;
|
||||
|
||||
size = readInt();
|
||||
|
||||
// get net size
|
||||
int nbytes = 0;
|
||||
for ( int i = 0; i < size; i++ )
|
||||
{
|
||||
aboffset += 4;
|
||||
int bodySize = readVarLengthUnsigned();
|
||||
aboffset += bodySize;
|
||||
nbytes += bodySize;
|
||||
}
|
||||
|
||||
// new array with only net data
|
||||
byte[] nab = new byte[nbytes];
|
||||
aboffset = 4;
|
||||
int noffset = 0;
|
||||
faid = new int[size];
|
||||
fapos = new int[size];
|
||||
|
||||
for ( int i = 0; i < size; i++ )
|
||||
{
|
||||
faid[i] = readInt() ^ 0x8000; // flip lat-sign for correct ordering
|
||||
|
||||
int bodySize = readVarLengthUnsigned();
|
||||
System.arraycopy( ab, aboffset, nab, noffset, bodySize );
|
||||
aboffset += bodySize;
|
||||
noffset += bodySize;
|
||||
fapos[i] = noffset;
|
||||
}
|
||||
|
||||
ab = nab;
|
||||
aboffset = noffset;
|
||||
init( size );
|
||||
}
|
||||
|
||||
@Override
|
||||
public long expandId( int id32 )
|
||||
{
|
||||
int lon32 = lonIdxBase + (short) ( id32 >> 16 );
|
||||
int lat32 = latIdxBase + (short) ( ( id32 & 0xffff ) ^ 0x8000 );
|
||||
return ( (long) lon32 ) << 32 | lat32;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int shrinkId( long id64 )
|
||||
{
|
||||
int lon32 = (int) ( id64 >> 32 );
|
||||
int lat32 = (int) ( id64 & 0xffffffff );
|
||||
return ( lon32 - lonIdxBase ) << 16 | ( ( ( lat32 - latIdxBase ) & 0xffff ) ^ 0x8000 );
|
||||
}
|
||||
|
||||
@Override
|
||||
public int encodeMicroCache( byte[] buffer )
|
||||
{
|
||||
ByteDataWriter dos = new ByteDataWriter( buffer );
|
||||
dos.writeInt( size );
|
||||
for ( int n = 0; n < size; n++ )
|
||||
{
|
||||
dos.writeInt( faid[n] ^ 0x8000 );
|
||||
int start = n > 0 ? fapos[n - 1] : 0;
|
||||
int end = fapos[n];
|
||||
int len = end - start;
|
||||
dos.writeVarLengthUnsigned( len );
|
||||
dos.write( ab, start, len );
|
||||
}
|
||||
return dos.size();
|
||||
}
|
||||
}
|
|
@ -108,10 +108,11 @@ final class OsmPath implements OsmLinkHolder
|
|||
|
||||
private void addAddionalPenalty(OsmTrack refTrack, boolean detailMode, OsmPath origin, OsmLink link, RoutingContext rc )
|
||||
{
|
||||
if ( link.descriptionBitmap == null ) throw new IllegalArgumentException( "null description for: " + link );
|
||||
byte[] description = link.descriptionBitmap;
|
||||
if ( description == null ) throw new IllegalArgumentException( "null description for: " + link );
|
||||
|
||||
boolean recordTransferNodes = detailMode || rc.countTraffic;
|
||||
boolean recordMessageData = detailMode;
|
||||
boolean recordTransferNodes = detailMode || rc.countTraffic;
|
||||
boolean recordMessageData = detailMode;
|
||||
|
||||
rc.nogomatch = false;
|
||||
|
||||
|
@ -126,7 +127,7 @@ final class OsmPath implements OsmLinkHolder
|
|||
|
||||
int linkdisttotal = 0;
|
||||
|
||||
MessageData msgData = new MessageData();
|
||||
MessageData msgData = recordMessageData ? new MessageData() : null;
|
||||
|
||||
OsmTransferNode transferNode = link.decodeFirsttransfer( p1 );
|
||||
OsmNode targetNode = link.targetNode;
|
||||
|
@ -138,27 +139,21 @@ final class OsmPath implements OsmLinkHolder
|
|||
int lon2;
|
||||
int lat2;
|
||||
short ele2;
|
||||
byte[] description;
|
||||
|
||||
if ( transferNode == null )
|
||||
{
|
||||
lon2 = targetNode.ilon;
|
||||
lat2 = targetNode.ilat;
|
||||
ele2 = targetNode.selev;
|
||||
description = link.descriptionBitmap;
|
||||
if ( description == null ) throw new IllegalArgumentException( "null description for class: " + link.getClass() );
|
||||
}
|
||||
else
|
||||
{
|
||||
lon2 = transferNode.ilon;
|
||||
lat2 = transferNode.ilat;
|
||||
ele2 = transferNode.selev;
|
||||
description = transferNode.descriptionBitmap;
|
||||
if ( description == null ) throw new IllegalArgumentException( "null description for class: " + transferNode.getClass() + "/" + link.getClass() + " counterlinkwritten=" + link.counterLinkWritten );
|
||||
}
|
||||
|
||||
rc.messageHandler.setCurrentPos( lon2, lat2 );
|
||||
boolean sameData = rc.expctxWay.evaluate( rc.inverseDirection ^ link.counterLinkWritten, description, rc.messageHandler );
|
||||
boolean sameData = rc.expctxWay.evaluate( rc.inverseDirection ^ link.counterLinkWritten, description );
|
||||
|
||||
// if way description changed, store message
|
||||
if ( recordMessageData && msgData.wayKeyValues != null )
|
||||
|
@ -198,7 +193,10 @@ final class OsmPath implements OsmLinkHolder
|
|||
}
|
||||
}
|
||||
|
||||
msgData.linkdist += dist;
|
||||
if ( recordMessageData )
|
||||
{
|
||||
msgData.linkdist += dist;
|
||||
}
|
||||
linkdisttotal += dist;
|
||||
|
||||
boolean isTrafficBackbone = cost == 0 && rc.expctxWay.getIsTrafficBackbone() > 0.f;
|
||||
|
@ -210,9 +208,9 @@ final class OsmPath implements OsmLinkHolder
|
|||
double cos = rc.calcCosAngle( lon0, lat0, lon1, lat1, lon2, lat2 );
|
||||
int turncost = (int)(cos * rc.expctxWay.getTurncost() + 0.2 ); // e.g. turncost=90 -> 90 degree = 90m penalty
|
||||
cost += turncost;
|
||||
msgData.linkturncost += turncost;
|
||||
if ( recordMessageData )
|
||||
{
|
||||
msgData.linkturncost += turncost;
|
||||
msgData.turnangle = (float)rc.calcAngle( lon0, lat0, lon1, lat1, lon2, lat2 );
|
||||
}
|
||||
}
|
||||
|
@ -250,7 +248,10 @@ final class OsmPath implements OsmLinkHolder
|
|||
{
|
||||
int elevationCost = reduce/rc.downhillcostdiv;
|
||||
cost += elevationCost;
|
||||
msgData.linkelevationcost += elevationCost;
|
||||
if ( recordMessageData )
|
||||
{
|
||||
msgData.linkelevationcost += elevationCost;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if ( ehbd < 0 )
|
||||
|
@ -280,7 +281,10 @@ final class OsmPath implements OsmLinkHolder
|
|||
{
|
||||
int elevationCost = reduce/rc.uphillcostdiv;
|
||||
cost += elevationCost;
|
||||
msgData.linkelevationcost += elevationCost;
|
||||
if ( recordMessageData )
|
||||
{
|
||||
msgData.linkelevationcost += elevationCost;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if ( ehbu < 0 )
|
||||
|
@ -313,6 +317,7 @@ final class OsmPath implements OsmLinkHolder
|
|||
cost += waycost;
|
||||
|
||||
// calculate traffic
|
||||
if ( rc.countTraffic )
|
||||
{
|
||||
int minDist = (int)rc.trafficSourceMinDist;
|
||||
int cost2 = cost < minDist ? minDist : cost;
|
||||
|
@ -330,7 +335,10 @@ final class OsmPath implements OsmLinkHolder
|
|||
lastClassifier = newClassifier;
|
||||
float initialcost = rc.expctxWay.getInitialcost();
|
||||
int iicost = (int)initialcost;
|
||||
msgData.linkinitcost += iicost;
|
||||
if ( recordMessageData )
|
||||
{
|
||||
msgData.linkinitcost += iicost;
|
||||
}
|
||||
cost += iicost;
|
||||
}
|
||||
|
||||
|
@ -402,8 +410,7 @@ final class OsmPath implements OsmLinkHolder
|
|||
if ( targetNode.nodeDescription != null )
|
||||
{
|
||||
boolean nodeAccessGranted = rc.expctxWay.getNodeAccessGranted() != 0.;
|
||||
rc.messageHandler.setCurrentPos( targetNode.ilon, targetNode.ilat );
|
||||
rc.expctxNode.evaluate( nodeAccessGranted , targetNode.nodeDescription, rc.messageHandler );
|
||||
rc.expctxNode.evaluate( nodeAccessGranted , targetNode.nodeDescription );
|
||||
float initialcost = rc.expctxNode.getInitialcost();
|
||||
if ( initialcost >= 1000000. )
|
||||
{
|
||||
|
@ -411,12 +418,12 @@ final class OsmPath implements OsmLinkHolder
|
|||
return;
|
||||
}
|
||||
int iicost = (int)initialcost;
|
||||
msgData.linknodecost += iicost;
|
||||
|
||||
cost += iicost;
|
||||
|
||||
if ( recordMessageData )
|
||||
{
|
||||
msgData.linknodecost += iicost;
|
||||
msgData.nodeKeyValues = rc.expctxNode.getKeyValueDescription( nodeAccessGranted, targetNode.nodeDescription );
|
||||
}
|
||||
}
|
||||
|
|
|
@ -111,8 +111,6 @@ public final class RoutingContext implements DistanceChecker
|
|||
turnInstructionRoundabouts = expctxGlobal.getVariableValue( "turnInstructionRoundabouts", 1.f ) != 0.f;
|
||||
}
|
||||
|
||||
public RoutingMessageHandler messageHandler = new RoutingMessageHandler();
|
||||
|
||||
public List<OsmNodeNamed> nogopoints = null;
|
||||
private List<OsmNodeNamed> keepnogopoints = null;
|
||||
|
||||
|
@ -222,10 +220,11 @@ public final class RoutingContext implements DistanceChecker
|
|||
|
||||
shortestmatch = false;
|
||||
|
||||
if ( d > 0. && nogopoints != null )
|
||||
if ( nogopoints != null && !nogopoints.isEmpty() && d > 0. )
|
||||
{
|
||||
for( OsmNodeNamed nogo : nogopoints )
|
||||
for( int ngidx = 0; ngidx < nogopoints.size(); ngidx++ )
|
||||
{
|
||||
OsmNodeNamed nogo = nogopoints.get(ngidx);
|
||||
double x1 = (lon1 - nogo.ilon) * coslat6;
|
||||
double y1 = (lat1 - nogo.ilat) * 0.000001;
|
||||
double x2 = (lon2 - nogo.ilon) * coslat6;
|
||||
|
|
|
@ -16,6 +16,7 @@ import btools.mapaccess.OsmLinkHolder;
|
|||
import btools.mapaccess.OsmNode;
|
||||
import btools.mapaccess.OsmNodesMap;
|
||||
import btools.util.SortedHeap;
|
||||
import btools.util.StackSampler;
|
||||
|
||||
public class RoutingEngine extends Thread
|
||||
{
|
||||
|
@ -43,6 +44,7 @@ public class RoutingEngine extends Thread
|
|||
private String logfileBase;
|
||||
private boolean infoLogEnabled;
|
||||
private Writer infoLogWriter;
|
||||
private StackSampler stackSampler;
|
||||
protected RoutingContext routingContext;
|
||||
|
||||
public double airDistanceCostFactor;
|
||||
|
@ -66,9 +68,10 @@ public class RoutingEngine extends Thread
|
|||
this.infoLogEnabled = outfileBase != null;
|
||||
this.routingContext = rc;
|
||||
|
||||
File baseFolder = new File( routingContext.localFunction ).getParentFile().getParentFile();
|
||||
try
|
||||
{
|
||||
File debugLog = new File( new File( routingContext.localFunction ).getParentFile(), "../debug.txt" );
|
||||
File debugLog = new File( baseFolder, "debug.txt" );
|
||||
if ( debugLog.exists() )
|
||||
{
|
||||
infoLogWriter = new FileWriter( debugLog, true );
|
||||
|
@ -80,6 +83,15 @@ public class RoutingEngine extends Thread
|
|||
{
|
||||
throw new RuntimeException( "cannot open debug-log:" + ioe );
|
||||
}
|
||||
|
||||
File stackLog = new File( baseFolder, "stacks.txt" );
|
||||
if ( stackLog.exists() )
|
||||
{
|
||||
stackSampler = new StackSampler( stackLog, 1000 );
|
||||
stackSampler.start();
|
||||
logInfo( "********** started stacksampling" );
|
||||
}
|
||||
|
||||
boolean cachedProfile = ProfileCache.parseProfile( rc );
|
||||
if ( hasInfo() )
|
||||
{
|
||||
|
@ -229,6 +241,13 @@ public class RoutingEngine extends Thread
|
|||
try { infoLogWriter.close(); } catch( Exception e ) {}
|
||||
infoLogWriter = null;
|
||||
}
|
||||
|
||||
if ( stackSampler != null )
|
||||
{
|
||||
try { stackSampler.close(); } catch( Exception e ) {}
|
||||
stackSampler = null;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -378,16 +397,6 @@ public class RoutingEngine extends Thread
|
|||
{
|
||||
preloadPosition( mwp.waypoint );
|
||||
}
|
||||
|
||||
// preliminary-hack: use old stuff if not yet matched
|
||||
for( int i=0; i<unmatchedWaypoints.size(); i++)
|
||||
{
|
||||
MatchedWaypoint mwp = unmatchedWaypoints.get(i);
|
||||
if ( mwp.crosspoint == null )
|
||||
{
|
||||
unmatchedWaypoints.set(i, matchNodeForPosition( mwp.waypoint ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void preloadPosition( OsmNode n )
|
||||
|
@ -408,93 +417,6 @@ public class RoutingEngine extends Thread
|
|||
}
|
||||
|
||||
|
||||
// geometric position matching finding the nearest routable way-section
|
||||
private MatchedWaypoint matchNodeForPosition( OsmNodeNamed wp )
|
||||
{
|
||||
try
|
||||
{
|
||||
routingContext.setWaypoint( wp, false );
|
||||
|
||||
int minRingWith = 1;
|
||||
for(;;)
|
||||
{
|
||||
MatchedWaypoint mwp = _matchNodeForPosition( wp, minRingWith );
|
||||
if ( mwp.node1 != null )
|
||||
{
|
||||
int mismatch = wp.calcDistance( mwp.crosspoint );
|
||||
if ( mismatch < 50*minRingWith )
|
||||
{
|
||||
return mwp;
|
||||
}
|
||||
}
|
||||
if ( minRingWith == 1 && nodesCache.first_file_access_failed )
|
||||
{
|
||||
throw new IllegalArgumentException( "datafile " + nodesCache.first_file_access_name + " not found" );
|
||||
}
|
||||
if ( minRingWith++ == 5 )
|
||||
{
|
||||
throw new IllegalArgumentException( wp.name + "-position not mapped in existing datafile" );
|
||||
}
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
routingContext.unsetWaypoint();
|
||||
}
|
||||
}
|
||||
|
||||
private MatchedWaypoint _matchNodeForPosition( OsmNodeNamed wp, int minRingWidth )
|
||||
{
|
||||
wp.radius = 1e9;
|
||||
resetCache();
|
||||
preloadPosition( wp, minRingWidth, 2000 );
|
||||
nodesCache.distanceChecker = routingContext;
|
||||
List<OsmNode> nodeList = nodesCache.getAllNodes();
|
||||
|
||||
MatchedWaypoint mwp = new MatchedWaypoint();
|
||||
mwp.waypoint = wp;
|
||||
|
||||
// first loop just to expand reverse links
|
||||
for( OsmNode n : nodeList )
|
||||
{
|
||||
if ( !nodesCache.obtainNonHollowNode( n ) )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
expandHollowLinkTargets( n );
|
||||
OsmLink startLink = new OsmLink();
|
||||
startLink.targetNode = n;
|
||||
OsmPath startPath = new OsmPath( startLink );
|
||||
startLink.addLinkHolder( startPath );
|
||||
for( OsmLink link = n.firstlink; link != null; link = link.next )
|
||||
{
|
||||
if ( link.descriptionBitmap == null ) continue; // reverse link not found
|
||||
OsmNode nextNode = link.targetNode;
|
||||
if ( nextNode.isHollow() ) continue; // border node?
|
||||
if ( nextNode.firstlink == null ) continue; // don't care about dead ends
|
||||
if ( nextNode == n ) continue; // ?
|
||||
double oldRadius = wp.radius;
|
||||
OsmPath testPath = new OsmPath( n, startPath, link, null, false, routingContext );
|
||||
if ( wp.radius < oldRadius )
|
||||
{
|
||||
if ( testPath.cost < 0 )
|
||||
{
|
||||
wp.radius = oldRadius; // no valid way
|
||||
}
|
||||
else
|
||||
{
|
||||
mwp.node1 = n;
|
||||
mwp.node2 = nextNode;
|
||||
mwp.radius = wp.radius;
|
||||
mwp.crosspoint = new OsmNodeNamed();
|
||||
mwp.crosspoint.ilon = routingContext.ilonshortest;
|
||||
mwp.crosspoint.ilat = routingContext.ilatshortest;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return mwp;
|
||||
}
|
||||
|
||||
// expand hollow link targets and resolve reverse links
|
||||
private void expandHollowLinkTargets( OsmNode n )
|
||||
|
|
|
@ -1,28 +0,0 @@
|
|||
/**
|
||||
* Container for routig configs
|
||||
*
|
||||
* @author ab
|
||||
*/
|
||||
package btools.router;
|
||||
|
||||
import btools.expressions.BExpressionReceiver;
|
||||
|
||||
final class RoutingMessageHandler implements BExpressionReceiver
|
||||
{
|
||||
private int ilon;
|
||||
private int ilat;
|
||||
|
||||
public void setCurrentPos( int lon, int lat)
|
||||
{
|
||||
ilon = lon;
|
||||
ilat = lat;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void expressionWarning( String context, String message )
|
||||
{
|
||||
System.out.println( "message (lon=" + (ilon-180000000) + " lat=" + (ilat-90000000)
|
||||
+ " context " + context + "): " + message );
|
||||
}
|
||||
}
|
|
@ -25,8 +25,6 @@ final class BExpression
|
|||
private static final int NUMBER_EXP = 33;
|
||||
private static final int VARIABLE_EXP = 34;
|
||||
|
||||
private static final int DUMPPOS_EXP = 40;
|
||||
|
||||
private int typ;
|
||||
private BExpression op1;
|
||||
private BExpression op2;
|
||||
|
@ -147,10 +145,6 @@ final class BExpression
|
|||
{
|
||||
exp.typ = NOT_EXP;
|
||||
}
|
||||
else if ( "dumppos".equals( operator ) )
|
||||
{
|
||||
exp.typ = DUMPPOS_EXP;
|
||||
}
|
||||
else
|
||||
{
|
||||
nops = 0; // check elemantary expressions
|
||||
|
@ -263,7 +257,6 @@ final class BExpression
|
|||
case NUMBER_EXP: return numberValue;
|
||||
case VARIABLE_EXP: return ctx.getVariableValue( variableIdx );
|
||||
case NOT_EXP: return op1.evaluate(ctx) == 0.f ? 1.f : 0.f;
|
||||
case DUMPPOS_EXP: ctx.expressionWarning( "INFO" ); return op1.evaluate(ctx);
|
||||
default: throw new IllegalArgumentException( "unknown op-code: " + typ );
|
||||
}
|
||||
}
|
||||
|
|
|
@ -31,8 +31,6 @@ public abstract class BExpressionContext
|
|||
private BufferedReader _br = null;
|
||||
private boolean _readerDone = false;
|
||||
|
||||
private BExpressionReceiver _receiver;
|
||||
|
||||
private Map<String,Integer> lookupNumbers = new HashMap<String,Integer>();
|
||||
private ArrayList<BExpressionLookupValue[]> lookupValues = new ArrayList<BExpressionLookupValue[]>();
|
||||
private ArrayList<String> lookupNames = new ArrayList<String>();
|
||||
|
@ -58,20 +56,21 @@ public abstract class BExpressionContext
|
|||
private byte[] currentByteArray = null;
|
||||
private boolean currentInverseDirection= false;
|
||||
|
||||
public List<BExpression> expressionList;
|
||||
private List<BExpression> expressionList;
|
||||
|
||||
private int minWriteIdx;
|
||||
|
||||
// build-in variable indexes for fast access
|
||||
private int[] buildInVariableIdx;
|
||||
|
||||
protected float[][] arrayBuildInVariablesCache;
|
||||
private float[][] arrayBuildInVariablesCache;
|
||||
private float[] hashBucketVars;
|
||||
|
||||
abstract String[] getBuildInVariableNames();
|
||||
|
||||
protected float getBuildInVariable( int idx )
|
||||
protected final float getBuildInVariable( int idx )
|
||||
{
|
||||
return arrayBuildInVariablesCache[idx][currentHashBucket];
|
||||
return hashBucketVars[idx];
|
||||
}
|
||||
|
||||
private int linenr;
|
||||
|
@ -105,10 +104,10 @@ public abstract class BExpressionContext
|
|||
|
||||
// create the build-in variables cache
|
||||
int nBuildInVars = getBuildInVariableNames().length;
|
||||
arrayBuildInVariablesCache = new float[nBuildInVars][];
|
||||
for( int vi=0; vi<nBuildInVars; vi++ )
|
||||
arrayBuildInVariablesCache = new float[hashSize][];
|
||||
for( int hi=0; hi<hashSize; hi++ )
|
||||
{
|
||||
arrayBuildInVariablesCache[vi] = new float[hashSize];
|
||||
arrayBuildInVariablesCache[hi] = new float[nBuildInVars];
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -264,9 +263,10 @@ public abstract class BExpressionContext
|
|||
public void evaluate( int[] lookupData2 )
|
||||
{
|
||||
lookupData = lookupData2;
|
||||
for( BExpression exp: expressionList)
|
||||
int n = expressionList.size();
|
||||
for( int expidx = 0; expidx < n; expidx++ )
|
||||
{
|
||||
exp.evaluate( this );
|
||||
expressionList.get( expidx ).evaluate( this );
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -279,7 +279,7 @@ public abstract class BExpressionContext
|
|||
*
|
||||
* @return true if the data is equivilant to the last calls data
|
||||
*/
|
||||
public boolean evaluate( boolean inverseDirection, byte[] ab, BExpressionReceiver receiver )
|
||||
public boolean evaluate( boolean inverseDirection, byte[] ab )
|
||||
{
|
||||
requests ++;
|
||||
lookupDataValid = false; // this is an assertion for a nasty pifall
|
||||
|
@ -291,6 +291,7 @@ public abstract class BExpressionContext
|
|||
int crc = Crc32.crcWithInverseBit(ab, inverseDirection ? inverseBitByteIndex : -1 );
|
||||
int hashSize = _arrayBitmap.length;
|
||||
currentHashBucket = (crc & 0xfffffff) % hashSize;
|
||||
hashBucketVars = arrayBuildInVariablesCache[currentHashBucket];
|
||||
currentByteArray = ab;
|
||||
currentInverseDirection = inverseDirection;
|
||||
byte[] abBucket = _arrayBitmap[currentHashBucket];
|
||||
|
@ -325,18 +326,15 @@ public abstract class BExpressionContext
|
|||
_arrayInverse[currentHashBucket] = currentInverseDirection;
|
||||
_arrayCrc[currentHashBucket] = crc;
|
||||
|
||||
_receiver = receiver;
|
||||
|
||||
decode( lookupData, currentInverseDirection, currentByteArray );
|
||||
evaluate( lookupData );
|
||||
|
||||
for( int vi=0; vi<buildInVariableIdx.length; vi++ )
|
||||
{
|
||||
int idx = buildInVariableIdx[vi];
|
||||
arrayBuildInVariablesCache[vi][currentHashBucket] = idx == -1 ? 0.f : variableData[idx];
|
||||
hashBucketVars[vi] = idx == -1 ? 0.f : variableData[idx];
|
||||
}
|
||||
|
||||
_receiver = null;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -763,9 +761,4 @@ public abstract class BExpressionContext
|
|||
return value;
|
||||
}
|
||||
|
||||
void expressionWarning( String message )
|
||||
{
|
||||
_arrayBitmap[currentHashBucket] = null; // no caching if warnings
|
||||
if ( _receiver != null ) _receiver.expressionWarning( context, message );
|
||||
}
|
||||
}
|
||||
|
|
|
@ -50,11 +50,11 @@ public final class BExpressionContextWay extends BExpressionContext implements T
|
|||
@Override
|
||||
public int accessType( byte[] description )
|
||||
{
|
||||
evaluate( false, description, null );
|
||||
evaluate( false, description );
|
||||
float minCostFactor = getCostfactor();
|
||||
if ( minCostFactor >= 9999.f )
|
||||
{
|
||||
evaluate( true, description, null );
|
||||
evaluate( true, description );
|
||||
float reverseCostFactor = getCostfactor();
|
||||
if ( reverseCostFactor < minCostFactor )
|
||||
{
|
||||
|
|
|
@ -1,7 +0,0 @@
|
|||
package btools.expressions;
|
||||
|
||||
|
||||
public interface BExpressionReceiver
|
||||
{
|
||||
public void expressionWarning( String context, String message );
|
||||
}
|
|
@ -39,7 +39,7 @@ public class EncodeDecodeTest
|
|||
byte[] description = expctxWay.encode(lookupData);
|
||||
|
||||
// calculate the cost factor from that description
|
||||
expctxWay.evaluate( false, description, null );
|
||||
expctxWay.evaluate( false, description );
|
||||
|
||||
float costfactor = expctxWay.getCostfactor();
|
||||
Assert.assertTrue( "costfactor mismatch", Math.abs( costfactor - 5.15 ) < 0.00001 );
|
||||
|
|
|
@ -156,9 +156,9 @@ public class OsmCutter extends MapCreatorBase
|
|||
if ( w.description == null ) return;
|
||||
|
||||
// filter according to profile
|
||||
_expctxWay.evaluate( false, w.description, null );
|
||||
_expctxWay.evaluate( false, w.description );
|
||||
boolean ok = _expctxWay.getCostfactor() < 10000.;
|
||||
_expctxWay.evaluate( true, w.description, null );
|
||||
_expctxWay.evaluate( true, w.description );
|
||||
ok |= _expctxWay.getCostfactor() < 10000.;
|
||||
if ( !ok ) return;
|
||||
|
||||
|
|
|
@ -10,18 +10,10 @@ import java.util.ArrayList;
|
|||
import java.util.HashMap;
|
||||
|
||||
import btools.codec.MicroCache;
|
||||
import btools.codec.MicroCache1;
|
||||
import btools.codec.MicroCache2;
|
||||
|
||||
public class OsmNodeP extends OsmLinkP
|
||||
{
|
||||
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 WRITEDESC_BITMASK = 0x10;
|
||||
public static final int SKIPDETAILS_BITMASK = 0x08;
|
||||
public static final int NODEDESC_BITMASK = 0x04;
|
||||
|
||||
/**
|
||||
* The latitude
|
||||
*/
|
||||
|
@ -104,151 +96,10 @@ public class OsmNodeP extends OsmLinkP
|
|||
return null;
|
||||
}
|
||||
|
||||
public void writeNodeData1( MicroCache1 mc ) throws IOException
|
||||
{
|
||||
mc.writeShort( getSElev() );
|
||||
|
||||
// hack: write node-desc as link tag (copy cycleway-bits)
|
||||
byte[] nodeDescription = getNodeDecsription();
|
||||
|
||||
for ( OsmLinkP link0 = getFirstLink(); link0 != null; link0 = link0.getNext( this ) )
|
||||
{
|
||||
int ilonref = ilon;
|
||||
int ilatref = ilat;
|
||||
|
||||
OsmLinkP link = link0;
|
||||
OsmNodeP origin = this;
|
||||
int skipDetailBit = link0.descriptionBitmap == null ? SKIPDETAILS_BITMASK : 0;
|
||||
|
||||
// first pass just to see if that link is consistent
|
||||
while (link != null)
|
||||
{
|
||||
OsmNodeP target = link.getTarget( origin );
|
||||
if ( !target.isTransferNode() )
|
||||
{
|
||||
break;
|
||||
}
|
||||
// next link is the one (of two), does does'nt point back
|
||||
for ( link = target.getFirstLink(); link != null; link = link.getNext( target ) )
|
||||
{
|
||||
if ( link.getTarget( target ) != origin )
|
||||
break;
|
||||
}
|
||||
origin = target;
|
||||
}
|
||||
if ( link == null )
|
||||
continue; // dead end
|
||||
|
||||
if ( skipDetailBit == 0 )
|
||||
{
|
||||
link = link0;
|
||||
origin = this;
|
||||
}
|
||||
byte[] lastDescription = null;
|
||||
while (link != null)
|
||||
{
|
||||
if ( link.descriptionBitmap == null && skipDetailBit == 0 )
|
||||
throw new IllegalArgumentException( "missing way description..." );
|
||||
|
||||
OsmNodeP target = link.getTarget( origin );
|
||||
int tranferbit = target.isTransferNode() ? TRANSFERNODE_BITMASK : 0;
|
||||
int nodedescbit = nodeDescription != null ? NODEDESC_BITMASK : 0;
|
||||
|
||||
int writedescbit = 0;
|
||||
if ( skipDetailBit == 0 ) // check if description changed
|
||||
{
|
||||
int inverseBitByteIndex = 0;
|
||||
boolean inverseDirection = link.isReverse( origin );
|
||||
byte[] ab = link.descriptionBitmap;
|
||||
int abLen = ab.length;
|
||||
int lastLen = lastDescription == null ? 0 : lastDescription.length;
|
||||
boolean equalsCurrent = abLen == lastLen;
|
||||
if ( equalsCurrent )
|
||||
{
|
||||
for ( int i = 0; i < abLen; i++ )
|
||||
{
|
||||
byte b = ab[i];
|
||||
if ( i == inverseBitByteIndex && inverseDirection )
|
||||
b ^= 1;
|
||||
if ( b != lastDescription[i] )
|
||||
{
|
||||
equalsCurrent = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if ( !equalsCurrent )
|
||||
{
|
||||
writedescbit = WRITEDESC_BITMASK;
|
||||
lastDescription = new byte[abLen];
|
||||
System.arraycopy( ab, 0, lastDescription, 0, abLen );
|
||||
if ( inverseDirection )
|
||||
lastDescription[inverseBitByteIndex] ^= 1;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
int bm = tranferbit | writedescbit | nodedescbit | skipDetailBit;
|
||||
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;
|
||||
}
|
||||
mc.writeByte( bm );
|
||||
|
||||
mc.writeVarLengthUnsigned( dlon );
|
||||
mc.writeVarLengthUnsigned( dlat );
|
||||
|
||||
if ( writedescbit != 0 )
|
||||
{
|
||||
// write the way description, code direction into the first bit
|
||||
mc.writeByte( lastDescription.length );
|
||||
mc.write( lastDescription );
|
||||
}
|
||||
if ( nodedescbit != 0 )
|
||||
{
|
||||
mc.writeByte( nodeDescription.length );
|
||||
mc.write( nodeDescription );
|
||||
nodeDescription = null;
|
||||
}
|
||||
|
||||
link.descriptionBitmap = null; // mark link as written
|
||||
|
||||
if ( tranferbit == 0 )
|
||||
{
|
||||
break;
|
||||
}
|
||||
mc.writeVarLengthSigned( target.getSElev() - getSElev() );
|
||||
// next link is the one (of two), does does'nt point back
|
||||
for ( link = target.getFirstLink(); link != null; link = link.getNext( target ) )
|
||||
{
|
||||
if ( link.getTarget( target ) != origin )
|
||||
break;
|
||||
}
|
||||
if ( link == null )
|
||||
throw new RuntimeException( "follow-up link not found for transfer-node!" );
|
||||
origin = target;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void writeNodeData( MicroCache mc ) throws IOException
|
||||
{
|
||||
boolean valid = true;
|
||||
if ( mc instanceof MicroCache1 )
|
||||
{
|
||||
writeNodeData1( (MicroCache1) mc );
|
||||
}
|
||||
else if ( mc instanceof MicroCache2 )
|
||||
if ( mc instanceof MicroCache2 )
|
||||
{
|
||||
valid = writeNodeData2( (MicroCache2) mc );
|
||||
}
|
||||
|
|
|
@ -124,11 +124,11 @@ public class RelationMerger extends MapCreatorBase
|
|||
{
|
||||
boolean ok = true;
|
||||
// check access and log a warning for conflicts
|
||||
expctxReport.evaluate( false, data.description, null );
|
||||
expctxReport.evaluate( false, data.description );
|
||||
boolean warn = expctxReport.getCostfactor() >= 10000.;
|
||||
if ( warn )
|
||||
{
|
||||
expctxCheck.evaluate( false, data.description, null );
|
||||
expctxCheck.evaluate( false, data.description );
|
||||
ok = expctxCheck.getCostfactor() < 10000.;
|
||||
|
||||
System.out.println( "** relation access conflict for wid = " + data.wid + " tags:" + expctxReport.getKeyValueDescription( false, data.description ) + " (ok=" + ok + ")" );
|
||||
|
|
|
@ -9,7 +9,6 @@ import java.util.TreeMap;
|
|||
|
||||
import btools.codec.DataBuffers;
|
||||
import btools.codec.MicroCache;
|
||||
import btools.codec.MicroCache1;
|
||||
import btools.codec.MicroCache2;
|
||||
import btools.codec.StatCoderContext;
|
||||
import btools.expressions.BExpressionContextWay;
|
||||
|
@ -57,7 +56,7 @@ public class WayLinker extends MapCreatorBase
|
|||
private int minLat;
|
||||
|
||||
private int microCacheEncoding = 2;
|
||||
private int divisor = microCacheEncoding == 2 ? 32 : 80;
|
||||
private int divisor = 32;
|
||||
private int cellsize = 1000000 / divisor;
|
||||
|
||||
private void reset()
|
||||
|
@ -186,9 +185,9 @@ public class WayLinker extends MapCreatorBase
|
|||
int lastTraffic = 0;
|
||||
|
||||
// filter according to profile
|
||||
expctxWay.evaluate( false, description, null );
|
||||
expctxWay.evaluate( false, description );
|
||||
boolean ok = expctxWay.getCostfactor() < 10000.;
|
||||
expctxWay.evaluate( true, description, null );
|
||||
expctxWay.evaluate( true, description );
|
||||
ok |= expctxWay.getCostfactor() < 10000.;
|
||||
if ( !ok )
|
||||
return;
|
||||
|
@ -330,8 +329,7 @@ public class WayLinker extends MapCreatorBase
|
|||
OsmNodeP n0 = subList.get( 0 );
|
||||
int lonIdxDiv = n0.ilon / cellsize;
|
||||
int latIdxDiv = n0.ilat / cellsize;
|
||||
MicroCache mc = microCacheEncoding == 0 ? new MicroCache1( size, abBuf2, lonIdxDiv, latIdxDiv ) : new MicroCache2( size, abBuf2,
|
||||
lonIdxDiv, latIdxDiv, divisor );
|
||||
MicroCache mc = new MicroCache2( size, abBuf2, lonIdxDiv, latIdxDiv, divisor );
|
||||
|
||||
// sort via treemap
|
||||
TreeMap<Integer, OsmNodeP> sortedList = new TreeMap<Integer, OsmNodeP>();
|
||||
|
@ -360,8 +358,7 @@ public class WayLinker extends MapCreatorBase
|
|||
System.arraycopy( abBuf1, 0, subBytes, 0, len );
|
||||
|
||||
// cross-check the encoding: re-instantiate the cache
|
||||
MicroCache mc2 = microCacheEncoding == 0 ? new MicroCache1( subBytes, lonIdxDiv, latIdxDiv ) : new MicroCache2( new DataBuffers(
|
||||
subBytes ), lonIdxDiv, latIdxDiv, divisor, null, null );
|
||||
MicroCache mc2 = new MicroCache2( new DataBuffers( subBytes ), lonIdxDiv, latIdxDiv, divisor, null, null );
|
||||
// ..and check if still the same
|
||||
String diffMessage = mc.compareWith( mc2 );
|
||||
if ( diffMessage != null )
|
||||
|
|
|
@ -35,8 +35,6 @@ public final class NodesCache
|
|||
private OsmFile[][] fileRows;
|
||||
private ArrayList<MicroCache> segmentList = new ArrayList<MicroCache>();
|
||||
|
||||
public DistanceChecker distanceChecker;
|
||||
|
||||
public WaypointMatcher waypointMatcher;
|
||||
|
||||
public boolean first_file_access_failed = false;
|
||||
|
@ -212,7 +210,7 @@ public final class NodesCache
|
|||
long id = node.getIdFromPos();
|
||||
if ( segment.getAndClear( id ) )
|
||||
{
|
||||
node.parseNodeBody( segment, nodesMap, distanceChecker );
|
||||
node.parseNodeBody( segment, nodesMap );
|
||||
}
|
||||
|
||||
if ( garbageCollectionEnabled ) // garbage collection
|
||||
|
|
|
@ -10,7 +10,6 @@ import java.io.RandomAccessFile;
|
|||
|
||||
import btools.codec.DataBuffers;
|
||||
import btools.codec.MicroCache;
|
||||
import btools.codec.MicroCache1;
|
||||
import btools.codec.MicroCache2;
|
||||
import btools.codec.TagValueValidator;
|
||||
import btools.codec.WaypointMatcher;
|
||||
|
@ -152,10 +151,6 @@ final class OsmFile
|
|||
|
||||
int crcData = Crc32.crc( ab, 0, asize - 4 );
|
||||
int crcFooter = new ByteDataReader( ab, asize - 4 ).readInt();
|
||||
if ( crcData == crcFooter )
|
||||
{
|
||||
return reallyDecode ? new MicroCache1( ab, lonIdx, latIdx ) : null;
|
||||
}
|
||||
if ( ( crcData ^ 2 ) == crcFooter )
|
||||
{
|
||||
return reallyDecode ? new MicroCache2( dataBuffers, lonIdx, latIdx, divisor, wayValidator, waypointMatcher ) : null;
|
||||
|
|
|
@ -26,21 +26,17 @@ public class OsmLink
|
|||
|
||||
public boolean counterLinkWritten;
|
||||
|
||||
public boolean hasNewGeometry; // preliminary
|
||||
|
||||
public byte state;
|
||||
|
||||
public void setGeometry( byte[] geometry )
|
||||
{
|
||||
this.geometry = geometry;
|
||||
hasNewGeometry = true;
|
||||
}
|
||||
|
||||
final public OsmTransferNode decodeFirsttransfer( OsmNode sourceNode )
|
||||
{
|
||||
if ( geometry == null ) return null;
|
||||
if ( hasNewGeometry )
|
||||
{
|
||||
if ( geometry == null ) return null;
|
||||
|
||||
OsmTransferNode firstTransferNode = null;
|
||||
OsmTransferNode lastTransferNode = null;
|
||||
OsmNode startnode = counterLinkWritten ? targetNode : sourceNode;
|
||||
|
@ -53,7 +49,6 @@ public class OsmLink
|
|||
OsmTransferNode trans = new OsmTransferNode();
|
||||
trans.ilon = olon + r.readVarLengthSigned();
|
||||
trans.ilat = olat + r.readVarLengthSigned();
|
||||
trans.descriptionBitmap = descriptionBitmap;
|
||||
trans.selev = (short)(oselev + r.readVarLengthSigned());
|
||||
olon = trans.ilon;
|
||||
olat = trans.ilat;
|
||||
|
@ -77,14 +72,6 @@ public class OsmLink
|
|||
}
|
||||
}
|
||||
return firstTransferNode;
|
||||
}
|
||||
return OsmTransferNode.decode( geometry );
|
||||
}
|
||||
|
||||
final public void encodeFirsttransfer( OsmTransferNode firsttransfer )
|
||||
{
|
||||
if ( firsttransfer == null ) geometry = null;
|
||||
else geometry = OsmTransferNode.encode( firsttransfer );
|
||||
}
|
||||
|
||||
final public void addLinkHolder( OsmLinkHolder holder )
|
||||
|
|
|
@ -6,22 +6,11 @@
|
|||
package btools.mapaccess;
|
||||
|
||||
import btools.codec.MicroCache;
|
||||
import btools.codec.MicroCache1;
|
||||
import btools.codec.MicroCache2;
|
||||
import btools.util.ByteArrayUnifier;
|
||||
|
||||
public class OsmNode implements OsmPos
|
||||
{
|
||||
public static final int EXTERNAL_BITMASK = 0x80; // old semantic
|
||||
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 WRITEDESC_BITMASK = 0x10;
|
||||
public static final int SKIPDETAILS_BITMASK = 0x08;
|
||||
public static final int NODEDESC_BITMASK = 0x04;
|
||||
public static final int RESERVED1_BITMASK = 0x02;
|
||||
public static final int RESERVED2_BITMASK = 0x01;
|
||||
|
||||
public OsmNode()
|
||||
{
|
||||
}
|
||||
|
@ -146,21 +135,17 @@ public class OsmNode implements OsmPos
|
|||
return "" + getIdFromPos();
|
||||
}
|
||||
|
||||
public void parseNodeBody( MicroCache mc, OsmNodesMap hollowNodes, DistanceChecker dc )
|
||||
public void parseNodeBody( MicroCache mc, OsmNodesMap hollowNodes )
|
||||
{
|
||||
if ( mc instanceof MicroCache1 )
|
||||
if ( mc instanceof MicroCache2 )
|
||||
{
|
||||
parseNodeBody1( (MicroCache1) mc, hollowNodes, dc );
|
||||
}
|
||||
else if ( mc instanceof MicroCache2 )
|
||||
{
|
||||
parseNodeBody2( (MicroCache2) mc, hollowNodes, dc );
|
||||
parseNodeBody2( (MicroCache2) mc, hollowNodes );
|
||||
}
|
||||
else
|
||||
throw new IllegalArgumentException( "unknown cache version: " + mc.getClass() );
|
||||
}
|
||||
|
||||
public void parseNodeBody2( MicroCache2 mc, OsmNodesMap hollowNodes, DistanceChecker dc )
|
||||
public void parseNodeBody2( MicroCache2 mc, OsmNodesMap hollowNodes )
|
||||
{
|
||||
ByteArrayUnifier abUnifier = hollowNodes.getByteArrayUnifier();
|
||||
|
||||
|
@ -184,10 +169,6 @@ public class OsmNode implements OsmPos
|
|||
}
|
||||
byte[] geometry = mc.readDataUntil( endPointer );
|
||||
|
||||
// preliminary hack: way-point-matching not here (done at decoding time)
|
||||
if ( dc != null )
|
||||
continue;
|
||||
|
||||
if ( linklon == ilon && linklat == ilat )
|
||||
{
|
||||
continue; // skip self-ref
|
||||
|
@ -236,186 +217,10 @@ public class OsmNode implements OsmPos
|
|||
rlink.setGeometry( geometry );
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
hollowNodes.remove( this );
|
||||
}
|
||||
|
||||
public void parseNodeBody1( MicroCache1 is, OsmNodesMap hollowNodes, DistanceChecker dc )
|
||||
{
|
||||
ByteArrayUnifier abUnifier = hollowNodes.getByteArrayUnifier();
|
||||
|
||||
selev = is.readShort();
|
||||
|
||||
while (is.hasMoreData())
|
||||
{
|
||||
int ilonref = ilon;
|
||||
int ilatref = ilat;
|
||||
|
||||
boolean counterLinkWritten = false;
|
||||
OsmTransferNode firstTransferNode = null;
|
||||
OsmTransferNode lastTransferNode = null;
|
||||
int linklon;
|
||||
int linklat;
|
||||
byte[] description = null;
|
||||
for ( ;; )
|
||||
{
|
||||
int bitField = is.readByte();
|
||||
int dlon = is.readVarLengthUnsigned();
|
||||
int dlat = is.readVarLengthUnsigned();
|
||||
if ( ( bitField & SIGNLON_BITMASK ) != 0 )
|
||||
{
|
||||
dlon = -dlon;
|
||||
}
|
||||
if ( ( bitField & SIGNLAT_BITMASK ) != 0 )
|
||||
{
|
||||
dlat = -dlat;
|
||||
}
|
||||
linklon = ilonref + dlon;
|
||||
linklat = ilatref + dlat;
|
||||
ilonref = linklon;
|
||||
ilatref = linklat;
|
||||
// read variable length or old 8 byte fixed, and ensure that 8 bytes is
|
||||
// only fixed
|
||||
if ( ( bitField & WRITEDESC_BITMASK ) != 0 )
|
||||
{
|
||||
byte[] ab = new byte[is.readByte()];
|
||||
is.readFully( ab );
|
||||
description = abUnifier.unify( ab );
|
||||
}
|
||||
if ( ( bitField & NODEDESC_BITMASK ) != 0 )
|
||||
{
|
||||
byte[] ab = new byte[is.readByte()];
|
||||
is.readFully( ab );
|
||||
nodeDescription = abUnifier.unify( ab );
|
||||
}
|
||||
if ( ( bitField & RESERVED1_BITMASK ) != 0 )
|
||||
{
|
||||
byte[] ab = new byte[is.readByte()];
|
||||
is.readFully( ab );
|
||||
}
|
||||
if ( ( bitField & RESERVED2_BITMASK ) != 0 )
|
||||
{
|
||||
byte[] ab = new byte[is.readByte()];
|
||||
is.readFully( ab );
|
||||
}
|
||||
if ( ( bitField & SKIPDETAILS_BITMASK ) != 0 )
|
||||
{
|
||||
counterLinkWritten = true;
|
||||
}
|
||||
|
||||
if ( description == null && !counterLinkWritten )
|
||||
throw new IllegalArgumentException( "internal error: missing way description!" );
|
||||
|
||||
boolean isTransfer = ( bitField & TRANSFERNODE_BITMASK ) != 0;
|
||||
if ( isTransfer )
|
||||
{
|
||||
OsmTransferNode trans = new OsmTransferNode();
|
||||
trans.ilon = linklon;
|
||||
trans.ilat = linklat;
|
||||
trans.descriptionBitmap = description;
|
||||
trans.selev = (short) ( selev + is.readVarLengthSigned() );
|
||||
if ( lastTransferNode == null )
|
||||
{
|
||||
firstTransferNode = trans;
|
||||
}
|
||||
else
|
||||
{
|
||||
lastTransferNode.next = trans;
|
||||
}
|
||||
lastTransferNode = trans;
|
||||
}
|
||||
else
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// performance shortcut: ignore link if out of reach
|
||||
if ( dc != null && !counterLinkWritten )
|
||||
{
|
||||
if ( !dc.isWithinRadius( ilon, ilat, firstTransferNode, linklon, linklat ) )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if ( linklon == ilon && linklat == ilat )
|
||||
{
|
||||
continue; // skip self-ref
|
||||
}
|
||||
|
||||
// first check the known links for that target
|
||||
OsmLink link = getCompatibleLink( linklon, linklat, counterLinkWritten, 2 );
|
||||
if ( link == null ) // .. not found, then check the hollow nodes
|
||||
{
|
||||
long targetNodeId = ( (long) linklon ) << 32 | linklat;
|
||||
OsmNode tn = hollowNodes.get( targetNodeId ); // target node
|
||||
if ( tn == null ) // node not yet known, create a new hollow proxy
|
||||
{
|
||||
tn = new OsmNode( linklon, linklat );
|
||||
tn.setHollow();
|
||||
hollowNodes.put( tn );
|
||||
}
|
||||
link = new OsmLink();
|
||||
link.targetNode = tn;
|
||||
link.counterLinkWritten = counterLinkWritten;
|
||||
link.state = 1;
|
||||
addLink( link );
|
||||
}
|
||||
|
||||
// now we have a link with a target node -> get the reverse link
|
||||
OsmLink rlink = link.targetNode.getCompatibleLink( ilon, ilat, !counterLinkWritten, 1 );
|
||||
if ( rlink == null ) // .. not found, create it
|
||||
{
|
||||
rlink = new OsmLink();
|
||||
rlink.targetNode = this;
|
||||
rlink.counterLinkWritten = !counterLinkWritten;
|
||||
rlink.state = 2;
|
||||
link.targetNode.addLink( rlink );
|
||||
}
|
||||
|
||||
if ( !counterLinkWritten )
|
||||
{
|
||||
// we have the data for that link, so fill both the link ..
|
||||
link.descriptionBitmap = description;
|
||||
link.encodeFirsttransfer( firstTransferNode );
|
||||
|
||||
// .. and the reverse
|
||||
if ( rlink.counterLinkWritten )
|
||||
{
|
||||
rlink.descriptionBitmap = description; // default for no
|
||||
// transfer-nodes
|
||||
OsmTransferNode previous = null;
|
||||
OsmTransferNode rtrans = null;
|
||||
for ( OsmTransferNode trans = firstTransferNode; trans != null; trans = trans.next )
|
||||
{
|
||||
if ( previous == null )
|
||||
{
|
||||
rlink.descriptionBitmap = trans.descriptionBitmap;
|
||||
}
|
||||
else
|
||||
{
|
||||
previous.descriptionBitmap = trans.descriptionBitmap;
|
||||
}
|
||||
rtrans = new OsmTransferNode();
|
||||
rtrans.ilon = trans.ilon;
|
||||
rtrans.ilat = trans.ilat;
|
||||
rtrans.selev = trans.selev;
|
||||
rtrans.next = previous;
|
||||
rtrans.descriptionBitmap = description;
|
||||
previous = rtrans;
|
||||
}
|
||||
rlink.encodeFirsttransfer( rtrans );
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
if ( dc == null )
|
||||
{
|
||||
hollowNodes.remove( this );
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isHollow()
|
||||
{
|
||||
|
|
|
@ -5,144 +5,15 @@
|
|||
*/
|
||||
package btools.mapaccess;
|
||||
|
||||
import btools.util.ByteDataReader;
|
||||
import btools.util.ByteDataWriter;
|
||||
|
||||
|
||||
|
||||
public final class OsmTransferNode
|
||||
{
|
||||
/**
|
||||
* The description bitmap is mainly the way description
|
||||
* used to calculate the costfactor
|
||||
*/
|
||||
public byte[] descriptionBitmap;
|
||||
|
||||
public OsmTransferNode next;
|
||||
|
||||
public int ilon;
|
||||
public int ilat;
|
||||
public short selev;
|
||||
|
||||
private static final int BIT_DESC = 1;
|
||||
private static final int BIT_ILONHIGH = 2;
|
||||
private static final int BIT_ILATHIGH = 4;
|
||||
private static final int BIT_STOP = 8;
|
||||
|
||||
// encode this transfer-node into a byte array
|
||||
public static byte[] encode( OsmTransferNode tn )
|
||||
{
|
||||
byte[] currentDesc = null;
|
||||
int currentILonHigh = 0;
|
||||
int currentILatHigh = 0;
|
||||
OsmTransferNode n = tn;
|
||||
|
||||
// first loop to calc size
|
||||
int size = 1; // stop-bit
|
||||
|
||||
while( n != null )
|
||||
{
|
||||
if ( n.descriptionBitmap == null ) throw new IllegalArgumentException( "transfernode-encode: description is null" );
|
||||
|
||||
if( n.descriptionBitmap != currentDesc )
|
||||
{
|
||||
currentDesc = n.descriptionBitmap;
|
||||
size += 1 + currentDesc.length;
|
||||
}
|
||||
if( ( n.ilon >> 16 ) != currentILonHigh )
|
||||
{
|
||||
size += 2;
|
||||
currentILonHigh = n.ilon >> 16;
|
||||
}
|
||||
if( (n.ilat >> 16) != currentILatHigh )
|
||||
{
|
||||
size += 2;
|
||||
currentILatHigh = n.ilat >> 16;
|
||||
}
|
||||
size += 7;
|
||||
n = n.next;
|
||||
}
|
||||
|
||||
byte[] ab = new byte[size];
|
||||
ByteDataWriter os = new ByteDataWriter( ab );
|
||||
|
||||
currentDesc = null;
|
||||
currentILonHigh = 0;
|
||||
currentILatHigh = 0;
|
||||
n = tn;
|
||||
while( n != null )
|
||||
{
|
||||
int mode = 0;
|
||||
if( n.descriptionBitmap != currentDesc )
|
||||
{
|
||||
mode |= BIT_DESC;
|
||||
currentDesc = n.descriptionBitmap;
|
||||
}
|
||||
if( ( n.ilon >> 16 ) != currentILonHigh )
|
||||
{
|
||||
mode |= BIT_ILONHIGH;
|
||||
currentILonHigh = n.ilon >> 16;
|
||||
}
|
||||
if( (n.ilat >> 16) != currentILatHigh )
|
||||
{
|
||||
mode |= BIT_ILATHIGH;
|
||||
currentILatHigh = n.ilat >> 16;
|
||||
}
|
||||
os.writeByte( mode);
|
||||
if ( (mode & BIT_DESC) != 0 ) { os.writeByte( currentDesc.length ); os.write( currentDesc ); }
|
||||
if ( (mode & BIT_ILONHIGH) != 0 ) os.writeShort( currentILonHigh );
|
||||
if ( (mode & BIT_ILATHIGH) != 0 ) os.writeShort( currentILatHigh );
|
||||
os.writeShort( n.ilon );
|
||||
os.writeShort( n.ilat );
|
||||
os.writeShort( n.selev );
|
||||
n = n.next;
|
||||
}
|
||||
os.writeByte( BIT_STOP );
|
||||
return ab;
|
||||
}
|
||||
|
||||
// decode a transfer-node from a byte array
|
||||
public static OsmTransferNode decode( byte[] ab )
|
||||
{
|
||||
ByteDataReader is = new ByteDataReader( ab );
|
||||
|
||||
OsmTransferNode firstNode = null;
|
||||
OsmTransferNode lastNode = null;
|
||||
byte[] currentDesc = null;
|
||||
int currentILonHigh = 0;
|
||||
int currentILatHigh = 0;
|
||||
|
||||
for(;;)
|
||||
{
|
||||
byte mode = is.readByte();
|
||||
if ( (mode & BIT_STOP ) != 0 ) break;
|
||||
|
||||
OsmTransferNode n = new OsmTransferNode();
|
||||
if ( (mode & BIT_DESC) != 0 ) { int dlen = is.readByte(); currentDesc = new byte[dlen]; is.readFully( currentDesc ); }
|
||||
if ( (mode & BIT_ILONHIGH) != 0 ) currentILonHigh = is.readShort();
|
||||
if ( (mode & BIT_ILATHIGH) != 0 ) currentILatHigh = is.readShort();
|
||||
n.descriptionBitmap = currentDesc;
|
||||
if ( n.descriptionBitmap == null ) throw new IllegalArgumentException( "transfernode-decode: description is null" );
|
||||
int ilon = is.readShort() & 0xffff; ilon |= currentILonHigh << 16;
|
||||
int ilat = is.readShort() & 0xffff; ilat |= currentILatHigh << 16;
|
||||
n.ilon = ilon;
|
||||
n.ilat = ilat;
|
||||
n.selev = is.readShort();
|
||||
|
||||
if ( ilon != n.ilon ) System.out.println( "ilon=" + ilon + " n.ilon=" + n.ilon );
|
||||
if ( ilat != n.ilat ) System.out.println( "ilat=" + ilat + " n.ilat=" + n.ilat );
|
||||
|
||||
if ( lastNode != null )
|
||||
{
|
||||
lastNode.next = n;
|
||||
}
|
||||
else
|
||||
{
|
||||
firstNode = n;
|
||||
}
|
||||
lastNode = n;
|
||||
}
|
||||
return firstNode;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -198,7 +198,7 @@ public class GraphLoader extends MapCreatorBase
|
|||
{
|
||||
if ( link.isWayLink() )
|
||||
{
|
||||
wayCtx.evaluate( false, link.descriptionBitmap, null );
|
||||
wayCtx.evaluate( false, link.descriptionBitmap );
|
||||
if ( wayCtx.getCostfactor() < 10000.f )
|
||||
{
|
||||
return true;
|
||||
|
|
|
@ -347,7 +347,7 @@ System.out.println( "*** finishedOffsets = " + finishedOffsets );
|
|||
else if ( link.isWayLink() )
|
||||
{
|
||||
// get costfactor
|
||||
rc.expctxWay.evaluate( link.isReverse( currentNode ), link.descriptionBitmap, null );
|
||||
rc.expctxWay.evaluate( link.isReverse( currentNode ), link.descriptionBitmap );
|
||||
|
||||
// *** penalty for distance
|
||||
float costfactor = rc.expctxWay.getCostfactor();
|
||||
|
@ -366,7 +366,7 @@ System.out.println( "*** finishedOffsets = " + finishedOffsets );
|
|||
|
||||
if ( node.getNodeDecsription() != null )
|
||||
{
|
||||
rc.expctxNode.evaluate( rc.expctxWay.getNodeAccessGranted() != 0., node.getNodeDecsription(), null );
|
||||
rc.expctxNode.evaluate( rc.expctxWay.getNodeAccessGranted() != 0., node.getNodeDecsription() );
|
||||
float initialcost = rc.expctxNode.getInitialcost();
|
||||
if ( initialcost >= 1000000. )
|
||||
{
|
||||
|
|
148
brouter-util/src/main/java/btools/util/StackSampler.java
Normal file
148
brouter-util/src/main/java/btools/util/StackSampler.java
Normal file
|
@ -0,0 +1,148 @@
|
|||
package btools.util;
|
||||
|
||||
import java.io.BufferedWriter;
|
||||
import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.OutputStreamWriter;
|
||||
import java.text.DateFormat;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Date;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.Random;
|
||||
|
||||
public class StackSampler extends Thread
|
||||
{
|
||||
private DateFormat df = new SimpleDateFormat( "yyyy-MM-dd HH:mm:ss,SSS", new Locale( "en", "US" ) );
|
||||
private BufferedWriter bw;
|
||||
private Random rand = new Random();
|
||||
|
||||
private int interval;
|
||||
private int flushCnt = 0;
|
||||
|
||||
private volatile boolean stopped;
|
||||
|
||||
public StackSampler( File logfile, int interval )
|
||||
{
|
||||
this.interval = interval;
|
||||
try
|
||||
{
|
||||
bw = new BufferedWriter( new OutputStreamWriter( new FileOutputStream( logfile, true ) ) );
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
printError( "StackSampler: " + e.getMessage() );
|
||||
}
|
||||
}
|
||||
|
||||
protected void printError( String msg )
|
||||
{
|
||||
System.out.println( msg );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run()
|
||||
{
|
||||
while( !stopped )
|
||||
{
|
||||
dumpThreads();
|
||||
}
|
||||
if ( bw != null )
|
||||
{
|
||||
try
|
||||
{
|
||||
bw.close();
|
||||
}
|
||||
catch( Exception e ) {}
|
||||
}
|
||||
}
|
||||
|
||||
public void dumpThreads()
|
||||
{
|
||||
try
|
||||
{
|
||||
int wait1 = rand.nextInt( interval );
|
||||
int wait2 = interval - wait1;
|
||||
Thread.sleep( wait1 );
|
||||
StringBuilder sb = new StringBuilder( df.format( new Date() ) + " THREADDUMP\n" );
|
||||
Map<Thread, StackTraceElement[]> allThreads = Thread.getAllStackTraces();
|
||||
for ( Map.Entry<Thread, StackTraceElement[]> e : allThreads.entrySet() )
|
||||
{
|
||||
Thread t = e.getKey();
|
||||
if ( t == Thread.currentThread() )
|
||||
{
|
||||
continue; // not me
|
||||
}
|
||||
|
||||
StackTraceElement[] stack = e.getValue();
|
||||
if ( !matchesFilter( stack ) )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
sb.append( " (ID=" ).append( t.getId() ).append( " \"" ).append( t.getName() ).append( "\" " ).append( t.getState() ).append( "\n" );
|
||||
for ( StackTraceElement line : stack )
|
||||
{
|
||||
sb.append( " " ).append( line.toString() ).append( "\n" );
|
||||
}
|
||||
sb.append( "\n" );
|
||||
}
|
||||
bw.write( sb.toString() );
|
||||
if ( flushCnt++ >= 0 )
|
||||
{
|
||||
flushCnt = 0;
|
||||
bw.flush();
|
||||
}
|
||||
Thread.sleep( wait2 );
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
// ignore
|
||||
}
|
||||
}
|
||||
|
||||
public void close()
|
||||
{
|
||||
stopped = true;
|
||||
interrupt();
|
||||
}
|
||||
|
||||
private boolean matchesFilter( StackTraceElement[] stack )
|
||||
{
|
||||
boolean positiveMatch = false;
|
||||
for ( StackTraceElement e : stack )
|
||||
{
|
||||
String s = e.toString();
|
||||
if ( s.indexOf( "btools" ) >= 0 )
|
||||
{
|
||||
positiveMatch = true;
|
||||
}
|
||||
if ( s.indexOf( "Thread.sleep" ) >= 0 )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return positiveMatch;
|
||||
}
|
||||
|
||||
public static void main( String[] args ) throws Exception
|
||||
{
|
||||
System.out.println( "StackSampler..." );
|
||||
Class<?> clazz = Class.forName( args[0] );
|
||||
String[] args2 = new String[args.length - 1];
|
||||
for ( int i = 1; i < args.length; i++ )
|
||||
{
|
||||
args2[i - 1] = args[i];
|
||||
}
|
||||
StackSampler t = new StackSampler( new File( "stacks.log" ), 1000 );
|
||||
t.start();
|
||||
try
|
||||
{
|
||||
clazz.getMethod( "main", String[].class ).invoke( null, new Object[]{ args2 } );
|
||||
}
|
||||
finally
|
||||
{
|
||||
t.close();
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue