Merge pull request #130 from Phyks/distance

Follow up on distance rework
This commit is contained in:
abrensch 2018-12-10 22:28:13 +01:00 committed by GitHub
commit d95a200070
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
21 changed files with 184 additions and 195 deletions

View file

@ -4,8 +4,8 @@ package btools.codec;
* Encoder/Decoder for signed integers that automatically detects the typical * Encoder/Decoder for signed integers that automatically detects the typical
* range of these numbers to determine a noisy-bit count as a very simple * range of these numbers to determine a noisy-bit count as a very simple
* dictionary * dictionary
* *
* Adapted for 3-pass encoding (counters -> statistics -> encoding ) * Adapted for 3-pass encoding (counters -> statistics -> encoding )
* but doesn't do anything at pass1 * but doesn't do anything at pass1
*/ */
public final class NoisyDiffCoder public final class NoisyDiffCoder

View file

@ -12,7 +12,7 @@ import btools.util.BitCoderContext;
* It detects identical descriptions and sorts them * It detects identical descriptions and sorts them
* into a huffman-tree according to their frequencies * into a huffman-tree according to their frequencies
* *
* Adapted for 3-pass encoding (counters -> statistics -> encoding ) * Adapted for 3-pass encoding (counters -> statistics -> encoding )
* but doesn't do anything at pass1 * but doesn't do anything at pass1
*/ */
public final class TagValueCoder public final class TagValueCoder
@ -124,9 +124,9 @@ public final class TagValueCoder
break; break;
} }
inum += delta; inum += delta;
int data = bc.decodeVarBits(); int data = bc.decodeVarBits();
if ( validator == null || validator.isLookupIdxUsed( inum ) ) if ( validator == null || validator.isLookupIdxUsed( inum ) )
{ {
hasdata = true; hasdata = true;

View file

@ -17,7 +17,7 @@ final class MatchedWaypoint
public OsmNode node2; public OsmNode node2;
public OsmNodeNamed crosspoint; public OsmNodeNamed crosspoint;
public OsmNodeNamed waypoint; public OsmNodeNamed waypoint;
public double radius; public double radius; // radius in meters
public boolean hasUpdate; public boolean hasUpdate;
public void writeToStream( DataOutput dos ) throws IOException public void writeToStream( DataOutput dos ) throws IOException
@ -40,7 +40,7 @@ final class MatchedWaypoint
mwp.node2 = new OsmNode(); mwp.node2 = new OsmNode();
mwp.crosspoint = new OsmNodeNamed(); mwp.crosspoint = new OsmNodeNamed();
mwp.waypoint = new OsmNodeNamed(); mwp.waypoint = new OsmNodeNamed();
mwp.node1.ilat = dis.readInt(); mwp.node1.ilat = dis.readInt();
mwp.node1.ilon = dis.readInt(); mwp.node1.ilon = dis.readInt();
mwp.node2.ilat = dis.readInt(); mwp.node2.ilat = dis.readInt();

View file

@ -10,15 +10,15 @@ import btools.mapaccess.OsmNode;
public class OsmNodeNamed extends OsmNode public class OsmNodeNamed extends OsmNode
{ {
public String name; public String name;
public double radius; // radius of nogopoint public double radius; // radius of nogopoint (in meters)
public boolean isNogo = false; public boolean isNogo = false;
@Override @Override
public String toString() public String toString()
{ {
return ilon + "," + ilat + "," + name; return ilon + "," + ilat + "," + name;
} }
public static OsmNodeNamed decodeNogo( String s ) public static OsmNodeNamed decodeNogo( String s )
{ {
OsmNodeNamed n = new OsmNodeNamed(); OsmNodeNamed n = new OsmNodeNamed();

View file

@ -103,36 +103,31 @@ public class OsmNogoPolygon extends OsmNodeNamed
int cx = (cxmax+cxmin) / 2; // center of circle int cx = (cxmax+cxmin) / 2; // center of circle
int cy = (cymax+cymin) / 2; int cy = (cymax+cymin) / 2;
double[] lonlat2m = CheapRulerSingleton.getLonLatToMeterScales( cy ); double[] lonlat2m = CheapRulerSingleton.getLonLatToMeterScales( cy );
double dlon2m = lonlat2m[0]; double dlon2m = lonlat2m[0];
double dlat2m = lonlat2m[1]; double dlat2m = lonlat2m[1];
double rad = 0; // radius double rad = 0; // radius
double rad2 = 0; // radius squared;
double dpx = 0; // x-xomponent of vector from center to point double dmax = 0; // length of vector from center to point
double dpy = 0; // y-component
double dmax2 = 0; // squared lenght of vector from center to point
int i_max = -1; int i_max = -1;
do do
{ // now identify the point outside of the circle that has the greatest distance {
for (int i = 0; i < points.size();i++) // now identify the point outside of the circle that has the greatest distance
for (int i = 0; i < points.size(); i++)
{ {
final Point p = points.get(i); final Point p = points.get(i);
final double dpix = (p.x - cx) * dlon2m; final double dist = CheapRulerSingleton.distance(p.x, p.y, (int) cx, (int) cy);
final double dpiy = (p.y - cy) * dlat2m; if (dist <= rad)
final double dist2 = dpix * dpix + dpiy * dpiy;
if (dist2 <= rad2)
{ {
continue; continue;
} }
if (dist2 > dmax2) if (dist > dmax)
{ {
dmax2 = dist2; // new maximum distance found // new maximum distance found
dpx = dpix / dlon2m; dmax = dist;
dpy = dpiy / dlat2m;
i_max = i; i_max = i;
} }
} }
@ -140,17 +135,13 @@ public class OsmNogoPolygon extends OsmNodeNamed
{ {
break; // leave loop when no point outside the circle is found any more. break; // leave loop when no point outside the circle is found any more.
} }
final double dist = Math.sqrt(dmax2); final double dd = 0.5 * (1 - rad / dmax);
final double dd = 0.5 * (dist - rad) / dist;
cx += (int)(dd * dpx + 0.5); // shift center toward point
cy += (int)(dd * dpy + 0.5);
final Point p = points.get(i_max); // calculate new radius to just include this point final Point p = points.get(i_max); // calculate new radius to just include this point
final double dpix = (p.x - cx) * dlon2m; cx += (int)(dd * (p.x - cx) + 0.5); // shift center toward point
final double dpiy = (p.y - cy) * dlat2m; cy += (int)(dd * (p.y - cy) + 0.5);
dmax2 = rad2 = dpix * dpix + dpiy * dpiy;
rad = Math.sqrt(rad2); dmax = rad = CheapRulerSingleton.distance(p.x, p.y, (int) cx, (int) cy);
i_max = -1; i_max = -1;
} }
while (true); while (true);
@ -254,10 +245,9 @@ public class OsmNogoPolygon extends OsmNodeNamed
/** /**
* winding number test for a point in a polygon * winding number test for a point in a polygon
* *
* @param p a point * @param px longitude of the point to check
* @param v list of vertex points forming a polygon. This polygon * @param py latitude of the point to check
* is implicitly closed connecting the last and first point. * @return a boolean whether the point is within the polygon or not.
* @return the winding number (=0 only when P is outside)
*/ */
public boolean isWithin(final long px, final long py) public boolean isWithin(final long px, final long py)
{ {

View file

@ -346,8 +346,9 @@ abstract class OsmPath implements OsmLinkHolder
if ( rc.startDirectionValid ) if ( rc.startDirectionValid )
{ {
double dir = rc.startDirection.intValue() / CheapRulerSingleton.DEG_TO_RAD; double dir = rc.startDirection.intValue() / CheapRulerSingleton.DEG_TO_RAD;
lon0 = lon1 - (int) ( 1000. * Math.sin( dir ) / rc.getCosLat() ); double[] lonlat2m = CheapRulerSingleton.getLonLatToMeterScales( (lon0 + lat1) >> 1 );
lat0 = lat1 - (int) ( 1000. * Math.cos( dir ) ); lon0 = lon1 - (int) ( 1000. * Math.sin( dir ) / lonlat2m[0] );
lat0 = lat1 - (int) ( 1000. * Math.cos( dir ) / lonlat2m[1] );
} }
else else
{ {

View file

@ -193,7 +193,6 @@ public final class RoutingContext
public Integer startDirection; public Integer startDirection;
public boolean startDirectionValid; public boolean startDirectionValid;
private double coslat;
private double cosangle; private double cosangle;
public boolean nogomatch = false; public boolean nogomatch = false;
public boolean isEndpoint = false; public boolean isEndpoint = false;
@ -248,8 +247,8 @@ public final class RoutingContext
try { ir = Integer.parseInt( s.substring( 4 ) ); } try { ir = Integer.parseInt( s.substring( 4 ) ); }
catch( Exception e ) { /* ignore */ } catch( Exception e ) { /* ignore */ }
} }
// TODO[Phyks] // Radius of the nogo point in meters
nogo.radius = ir / 110984.; // 6378000. / 57.3; nogo.radius = ir;
} }
} }
@ -259,12 +258,10 @@ public final class RoutingContext
List<OsmNodeNamed> nogos = new ArrayList<OsmNodeNamed>(); List<OsmNodeNamed> nogos = new ArrayList<OsmNodeNamed>();
for( OsmNodeNamed nogo : nogopoints ) for( OsmNodeNamed nogo : nogopoints )
{ {
// TODO[Phyks]
int radiusInMeter = (int)(nogo.radius * 111894.);
boolean goodGuy = true; boolean goodGuy = true;
for( OsmNodeNamed wp : waypoints ) for( OsmNodeNamed wp : waypoints )
{ {
if ( wp.calcDistance( nogo ) < radiusInMeter if ( wp.calcDistance( nogo ) < nogo.radius
&& (!(nogo instanceof OsmNogoPolygon) && (!(nogo instanceof OsmNogoPolygon)
|| (((OsmNogoPolygon)nogo).isClosed || (((OsmNogoPolygon)nogo).isClosed
? ((OsmNogoPolygon)nogo).isWithin(wp.ilon, wp.ilat) ? ((OsmNogoPolygon)nogo).isWithin(wp.ilon, wp.ilat)
@ -288,6 +285,7 @@ public final class RoutingContext
OsmNodeNamed nogo = nogopoints.get(i); OsmNodeNamed nogo = nogopoints.get(i);
cs[0] += nogo.ilon; cs[0] += nogo.ilon;
cs[1] += nogo.ilat; cs[1] += nogo.ilat;
// 10 is an arbitrary constant to get sub-integer precision in the checksum
cs[2] += (long) ( nogo.radius*10.); cs[2] += (long) ( nogo.radius*10.);
} }
return cs; return cs;
@ -342,7 +340,7 @@ public final class RoutingContext
if ( s2 > 0. ) if ( s2 > 0. )
{ {
radius = Math.sqrt( s1 < s2 ? r12 : r22 ); radius = Math.sqrt( s1 < s2 ? r12 : r22 );
if ( radius > nogo.radius ) continue; // 20m ^ 2 if ( radius > nogo.radius ) continue;
} }
if ( nogo.isNogo ) if ( nogo.isNogo )
{ {
@ -404,28 +402,23 @@ public final class RoutingContext
return (int)(d + 1.0 ); return (int)(d + 1.0 );
} }
// assumes that calcDistance/calcCosAngle called in sequence, so coslat valid
public double getCosAngle() public double getCosAngle()
{ {
return cosangle; return cosangle;
} }
public double getCosLat()
{
return coslat;
}
public double calcAngle( int lon0, int lat0, int lon1, int lat1, int lon2, int lat2 ) public double calcAngle( int lon0, int lat0, int lon1, int lat1, int lon2, int lat2 )
{ {
double dlat1 = (lat1 - lat0); double[] lonlat2m = CheapRulerSingleton.getLonLatToMeterScales( lat1 );
double dlon1 = (lon1 - lon0) * coslat; double dy10 = (lat1 - lat0) * lonlat2m[1];
double dlat2 = (lat2 - lat1); double dx10 = (lon1 - lon0) * lonlat2m[0];
double dlon2 = (lon2 - lon1) * coslat; double dy21 = (lat2 - lat1) * lonlat2m[1];
double dx21 = (lon2 - lon1) * lonlat2m[0];
double dd = Math.sqrt( (dlat1*dlat1 + dlon1*dlon1)*(dlat2*dlat2 + dlon2*dlon2) ); double dd = Math.sqrt( (dx10*dx10 + dy10*dy10)*(dx21*dx21 + dy21*dy21) );
if ( dd == 0. ) { cosangle = 1.; return 0.; } if ( dd == 0. ) { cosangle = 1.; return 0.; }
double sinp = (dlat1*dlon2 - dlon1*dlat2)/dd; double sinp = (dy10*dy21 - dx10*dx21)/dd;
double cosp = (dlat1*dlat2 + dlon1*dlon2)/dd; double cosp = (dy10*dy21 + dx10*dx21)/dd;
cosangle = cosp; cosangle = cosp;
double p; double p;

View file

@ -22,19 +22,22 @@ public final class SearchBoundary
private int maxlat; private int maxlat;
private int radius; private int radius;
private OsmNode p; private OsmNode p;
int direction; int direction;
/**
* @param radius Search radius in meters.
*/
public SearchBoundary( OsmNode n, int radius, int direction ) public SearchBoundary( OsmNode n, int radius, int direction )
{ {
this.radius = radius; this.radius = radius;
this.direction = direction; this.direction = direction;
p = new OsmNode( n.ilon, n.ilat ); p = new OsmNode( n.ilon, n.ilat );
int lon = (n.ilon / 5000000 ) * 5000000; int lon = (n.ilon / 5000000 ) * 5000000;
int lat = (n.ilat / 5000000 ) * 5000000; int lat = (n.ilat / 5000000 ) * 5000000;
minlon0 = lon - 5000000; minlon0 = lon - 5000000;
minlat0 = lat - 5000000; minlat0 = lat - 5000000;
maxlon0 = lon + 10000000; maxlon0 = lon + 10000000;
@ -45,12 +48,12 @@ public final class SearchBoundary
maxlon = lon + 6000000; maxlon = lon + 6000000;
maxlat = lat + 6000000; maxlat = lat + 6000000;
} }
public static String getFileName( OsmNode n ) public static String getFileName( OsmNode n )
{ {
int lon = (n.ilon / 5000000 ) * 5000000; int lon = (n.ilon / 5000000 ) * 5000000;
int lat = (n.ilat / 5000000 ) * 5000000; int lat = (n.ilat / 5000000 ) * 5000000;
int dlon = lon / 1000000 -180; int dlon = lon / 1000000 -180;
int dlat = lat / 1000000 - 90; int dlat = lat / 1000000 - 90;
@ -58,7 +61,7 @@ public final class SearchBoundary
String slat = dlat < 0 ? "S" + (-dlat) : "N" + dlat; String slat = dlat < 0 ? "S" + (-dlat) : "N" + dlat;
return slon + "_" + slat + ".trf"; return slon + "_" + slat + ".trf";
} }
public boolean isInBoundary( OsmNode n, int cost ) public boolean isInBoundary( OsmNode n, int cost )
{ {
if ( radius > 0 ) if ( radius > 0 )
@ -83,5 +86,5 @@ public final class SearchBoundary
default: throw new IllegalArgumentException( "undefined direction: "+ direction ); default: throw new IllegalArgumentException( "undefined direction: "+ direction );
} }
} }
} }

View file

@ -33,8 +33,7 @@ public final class WaypointMatcherImpl implements WaypointMatcher
this.islandPairs = islandPairs; this.islandPairs = islandPairs;
for ( MatchedWaypoint mwp : waypoints ) for ( MatchedWaypoint mwp : waypoints )
{ {
// TODO[Phyks] mwp.radius = maxDistance;
mwp.radius = maxDistance * 110984.; // 6378000. / 57.3;
} }
} }
@ -49,6 +48,7 @@ public final class WaypointMatcherImpl implements WaypointMatcher
double dx = ( lon2 - lon1 ) * dlon2m; double dx = ( lon2 - lon1 ) * dlon2m;
double dy = ( lat2 - lat1 ) * dlat2m; double dy = ( lat2 - lat1 ) * dlat2m;
double d = Math.sqrt( dy * dy + dx * dx ); double d = Math.sqrt( dy * dy + dx * dx );
if ( d == 0. ) if ( d == 0. )
return; return;

View file

@ -28,12 +28,12 @@ public abstract class BExpressionContext implements IByteArrayUnifier
{ {
private static final String CONTEXT_TAG = "---context:"; private static final String CONTEXT_TAG = "---context:";
private static final String MODEL_TAG = "---model:"; private static final String MODEL_TAG = "---model:";
private String context; private String context;
private boolean _inOurContext = false; private boolean _inOurContext = false;
private BufferedReader _br = null; private BufferedReader _br = null;
private boolean _readerDone = false; private boolean _readerDone = false;
public String _modelClass; public String _modelClass;
private Map<String,Integer> lookupNumbers = new HashMap<String,Integer>(); private Map<String,Integer> lookupNumbers = new HashMap<String,Integer>();
@ -49,7 +49,7 @@ public abstract class BExpressionContext implements IByteArrayUnifier
private byte[] abBuf = new byte[256]; private byte[] abBuf = new byte[256];
private BitCoderContext ctxEndode = new BitCoderContext( abBuf ); private BitCoderContext ctxEndode = new BitCoderContext( abBuf );
private BitCoderContext ctxDecode = new BitCoderContext( new byte[0] ); private BitCoderContext ctxDecode = new BitCoderContext( new byte[0] );
private Map<String,Integer> variableNumbers = new HashMap<String,Integer>(); private Map<String,Integer> variableNumbers = new HashMap<String,Integer>();
private float[] variableData; private float[] variableData;
@ -69,12 +69,12 @@ public abstract class BExpressionContext implements IByteArrayUnifier
// build-in variable indexes for fast access // build-in variable indexes for fast access
private int[] buildInVariableIdx; private int[] buildInVariableIdx;
private int nBuildInVars; private int nBuildInVars;
private float[] currentVars; private float[] currentVars;
private int currentVarOffset; private int currentVarOffset;
private BExpressionContext foreignContext; private BExpressionContext foreignContext;
protected void setInverseVars() protected void setInverseVars()
{ {
currentVarOffset = nBuildInVars; currentVarOffset = nBuildInVars;
@ -82,7 +82,7 @@ public abstract class BExpressionContext implements IByteArrayUnifier
abstract String[] getBuildInVariableNames(); abstract String[] getBuildInVariableNames();
public final float getBuildInVariable( int idx ) public final float getBuildInVariable( int idx )
{ {
return currentVars[idx+currentVarOffset]; return currentVars[idx+currentVarOffset];
} }
@ -107,11 +107,11 @@ public abstract class BExpressionContext implements IByteArrayUnifier
{ {
this.context = context; this.context = context;
this.meta = meta; this.meta = meta;
if ( meta != null ) meta.registerListener(context, this ); if ( meta != null ) meta.registerListener(context, this );
if ( Boolean.getBoolean( "disableExpressionCache" ) ) hashSize = 1; if ( Boolean.getBoolean( "disableExpressionCache" ) ) hashSize = 1;
// create the expression cache // create the expression cache
if ( hashSize > 0 ) if ( hashSize > 0 )
{ {
@ -133,12 +133,12 @@ public abstract class BExpressionContext implements IByteArrayUnifier
{ {
BitCoderContext ctx = ctxEndode; BitCoderContext ctx = ctxEndode;
ctx.reset(); ctx.reset();
int skippedTags = 0; int skippedTags = 0;
int nonNullTags= 0; int nonNullTags= 0;
// (skip first bit ("reversedirection") ) // (skip first bit ("reversedirection") )
// all others are generic // all others are generic
for( int inum = 1; inum < lookupValues.size(); inum++ ) // loop over lookup names for( int inum = 1; inum < lookupValues.size(); inum++ ) // loop over lookup names
{ {
@ -151,29 +151,29 @@ public abstract class BExpressionContext implements IByteArrayUnifier
ctx.encodeVarBits( 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.encodeVarBits( dd ); ctx.encodeVarBits( dd );
} }
ctx.encodeVarBits( 0 ); ctx.encodeVarBits( 0 );
if ( nonNullTags == 0) return null; if ( nonNullTags == 0) return null;
int len = ctx.getEncodedLength(); int len = ctx.getEncodedLength();
byte[] ab = new byte[len]; byte[] ab = new byte[len];
System.arraycopy( abBuf, 0, ab, 0, len ); System.arraycopy( abBuf, 0, ab, 0, len );
// crosscheck: decode and compare // crosscheck: decode and compare
int[] ld2 = new int[lookupValues.size()]; int[] ld2 = new int[lookupValues.size()];
decode( ld2, false, ab ); decode( ld2, false, ab );
for( int inum = 1; inum < lookupValues.size(); inum++ ) // loop over lookup names (except reverse dir) for( int inum = 1; inum < lookupValues.size(); inum++ ) // loop over lookup names (except reverse dir)
{ {
if ( ld2[inum] != ld[inum] ) throw new RuntimeException( "assertion failed encoding inum=" + inum + " val=" + ld[inum] + " " + getKeyValueDescription(false, ab) ); if ( ld2[inum] != ld[inum] ) throw new RuntimeException( "assertion failed encoding inum=" + inum + " val=" + ld[inum] + " " + getKeyValueDescription(false, ab) );
} }
return ab; return ab;
} }
@ -186,7 +186,7 @@ public abstract class BExpressionContext implements IByteArrayUnifier
decode( lookupData, false, ab ); decode( lookupData, false, ab );
lookupDataValid = true; lookupDataValid = true;
} }
/** /**
@ -196,10 +196,10 @@ public abstract class BExpressionContext implements IByteArrayUnifier
{ {
BitCoderContext ctx = ctxDecode; BitCoderContext ctx = ctxDecode;
ctx.reset( ab ); ctx.reset( ab );
// start with first bit hardwired ("reversedirection") // start with first bit hardwired ("reversedirection")
ld[0] = inverseDirection ? 2 : 0; ld[0] = inverseDirection ? 2 : 0;
// all others are generic // all others are generic
int inum = 1; int inum = 1;
for(;;) for(;;)
@ -207,7 +207,7 @@ public abstract class BExpressionContext implements IByteArrayUnifier
int delta = ctx.decodeVarBits(); 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
@ -255,7 +255,7 @@ public abstract class BExpressionContext implements IByteArrayUnifier
private int parsedLines = 0; private int parsedLines = 0;
private boolean fixTagsWritten = false; private boolean fixTagsWritten = false;
public void parseMetaLine( String line ) public void parseMetaLine( String line )
{ {
parsedLines++; parsedLines++;
@ -278,7 +278,7 @@ public abstract class BExpressionContext implements IByteArrayUnifier
// add aliases // add aliases
while( newValue != null && tk.hasMoreTokens() ) newValue.addAlias( tk.nextToken() ); while( newValue != null && tk.hasMoreTokens() ) newValue.addAlias( tk.nextToken() );
} }
public void finishMetaParsing() public void finishMetaParsing()
{ {
if ( parsedLines == 0 && !"global".equals(context) ) if ( parsedLines == 0 && !"global".equals(context) )
@ -288,7 +288,7 @@ public abstract class BExpressionContext implements IByteArrayUnifier
// post-process metadata: // post-process metadata:
lookupDataFrozen = true; lookupDataFrozen = true;
lookupIdxUsed = new boolean[lookupValues.size()]; lookupIdxUsed = new boolean[lookupValues.size()];
} }
@ -310,12 +310,12 @@ public abstract class BExpressionContext implements IByteArrayUnifier
private long requests; private long requests;
private long requests2; private long requests2;
private long cachemisses; private long cachemisses;
public String cacheStats() public String cacheStats()
{ {
return "requests=" + requests + " requests2=" + requests2 + " cachemisses=" + cachemisses; return "requests=" + requests + " requests2=" + requests2 + " cachemisses=" + cachemisses;
} }
private CacheNode lastCacheNode = new CacheNode(); private CacheNode lastCacheNode = new CacheNode();
// @Override // @Override
@ -355,7 +355,7 @@ public abstract class BExpressionContext implements IByteArrayUnifier
{ {
requests++; requests++;
lookupDataValid = false; // this is an assertion for a nasty pifall lookupDataValid = false; // this is an assertion for a nasty pifall
if ( cache == null ) if ( cache == null )
{ {
decode( lookupData, inverseDirection, ab ); decode( lookupData, inverseDirection, ab );
@ -383,7 +383,7 @@ public abstract class BExpressionContext implements IByteArrayUnifier
if ( cn == null ) if ( cn == null )
{ {
cachemisses++; cachemisses++;
cn = (CacheNode)cache.removeLru(); cn = (CacheNode)cache.removeLru();
if ( cn == null ) if ( cn == null )
{ {
@ -405,9 +405,9 @@ public abstract class BExpressionContext implements IByteArrayUnifier
// inverse direction // inverse direction
lookupData[0] = 2; // inverse shortcut: reuse decoding lookupData[0] = 2; // inverse shortcut: reuse decoding
evaluateInto( probeVarSet.vars, nBuildInVars ); evaluateInto( probeVarSet.vars, nBuildInVars );
probeVarSet.hash = Arrays.hashCode( probeVarSet.vars ); probeVarSet.hash = Arrays.hashCode( probeVarSet.vars );
// unify the result variable set // unify the result variable set
VarWrapper vw = (VarWrapper)resultVarCache.get( probeVarSet ); VarWrapper vw = (VarWrapper)resultVarCache.get( probeVarSet );
if ( vw == null ) if ( vw == null )
@ -427,7 +427,7 @@ public abstract class BExpressionContext implements IByteArrayUnifier
else else
{ {
if ( ab == cn.ab ) requests2++; if ( ab == cn.ab ) requests2++;
cache.touch( cn ); cache.touch( cn );
} }
@ -647,7 +647,7 @@ public abstract class BExpressionContext implements IByteArrayUnifier
/** /**
* special hack for yes/proposed relations: * special hack for yes/proposed relations:
* add a lookup value if not yet a smaller, >1 value was added * add a lookup value if not yet a smaller, &gt; 1 value was added
* add a 2=yes if the provided value is out of range * add a 2=yes if the provided value is out of range
* value-index means here 0=unknown, 1=other, 2=yes, 3=proposed * value-index means here 0=unknown, 1=other, 2=yes, 3=proposed
*/ */
@ -680,7 +680,7 @@ public abstract class BExpressionContext implements IByteArrayUnifier
Integer num = lookupNumbers.get( name ); Integer num = lookupNumbers.get( name );
return num != null && lookupData[num.intValue()] == 2; return num != null && lookupData[num.intValue()] == 2;
} }
public int getOutputVariableIndex( String name, boolean mustExist ) public int getOutputVariableIndex( String name, boolean mustExist )
{ {
int idx = getVariableIdx( name, false ); int idx = getVariableIdx( name, false );
@ -708,7 +708,7 @@ public abstract class BExpressionContext implements IByteArrayUnifier
buildInVariableIdx = extended; buildInVariableIdx = extended;
return nBuildInVars++; return nBuildInVars++;
} }
public void setForeignContext( BExpressionContext foreignContext ) public void setForeignContext( BExpressionContext foreignContext )
{ {
this.foreignContext = foreignContext; this.foreignContext = foreignContext;
@ -855,7 +855,7 @@ public abstract class BExpressionContext implements IByteArrayUnifier
{ {
lookupIdxUsed[ idx ] = true; lookupIdxUsed[ idx ] = true;
} }
public final boolean isLookupIdxUsed( int idx ) public final boolean isLookupIdxUsed( int idx )
{ {
return idx < lookupIdxUsed.length ? lookupIdxUsed[idx] : false; return idx < lookupIdxUsed.length ? lookupIdxUsed[idx] : false;

View file

@ -14,7 +14,7 @@ public final class BitReadBuffer
this.ab = ab; this.ab = ab;
idxMax = ab.length-1; idxMax = ab.length-1;
} }
public boolean decodeBit() public boolean decodeBit()
{ {
fillBuffer(); fillBuffer();
@ -60,10 +60,10 @@ public final class BitReadBuffer
/** /**
* decode a small number with a variable bit length * decode a small number with a variable bit length
* (poor mans huffman tree) * (poor mans huffman tree)
* 1 -> 0 * {@code 1 -> 0}
* 01 -> 1 + following 1-bit word ( 1..2 ) * {@code 01 -> 1} + following 1-bit word ( 1..2 )
* 001 -> 3 + following 2-bit word ( 3..6 ) * {@code 001 -> 3} + following 2-bit word ( 3..6 )
* 0001 -> 7 + following 3-bit word ( 7..14 ) etc. * {@code 0001 -> 7} + following 3-bit word ( 7..14 ) etc.
*/ */
public int decodeInt() public int decodeInt()
{ {
@ -139,7 +139,7 @@ public final class BitReadBuffer
} }
} }
private void fillBuffer() private void fillBuffer()
{ {
while (bits <= 56) while (bits <= 56)
@ -150,5 +150,5 @@ public final class BitReadBuffer
} }
bits += 8; bits += 8;
} }
} }
} }

View file

@ -23,12 +23,13 @@ public final class BitWriteBuffer
/** /**
* encode a distance with a variable bit length * encode a distance with a variable bit length
* (poor mans huffman tree) * (poor mans huffman tree)
* 1 -> 0 * {@code 1 -> 0}
* 01 -> 1 + following 1-bit word ( 1..2 ) * {@code 01 -> 1} + following 1-bit word ( 1..2 )
* 001 -> 3 + following 2-bit word ( 3..6 ) * {@code 001 -> 3} + following 2-bit word ( 3..6 )
* 0001 -> 7 + following 3-bit word ( 7..14 ) etc. * {@code 0001 -> 7} + following 3-bit word ( 7..14 ) etc.
* *
* @see #decodeVarBits * @see btools.util.BitCoderContext#decodeVarBits
*
*/ */
public void encodeInt( int value ) public void encodeInt( int value )
{ {
@ -39,7 +40,7 @@ public final class BitWriteBuffer
value -= range + 1; value -= range + 1;
range = 2 * range + 1; range = 2 * range + 1;
} }
encodeBit( true ); encodeBit( true );
encodeBounded( range, value ); encodeBounded( range, value );
} }
@ -127,7 +128,7 @@ public final class BitWriteBuffer
if ( size == 0 ) if ( size == 0 )
{ {
return; return;
} }
long maxValue = values[size-1]; long maxValue = values[size-1];
int nbits = 0; int nbits = 0;
while ( maxValue > 0 ) while ( maxValue > 0 )
@ -187,7 +188,7 @@ public final class BitWriteBuffer
/** /**
* assign the de-/encoded bits since the last call assignBits to the given * assign the de-/encoded bits since the last call assignBits to the given
* name. Used for encoding statistics * name. Used for encoding statistics
* *
* @see #getBitReport * @see #getBitReport
*/ */
public void assignBits( String name ) public void assignBits( String name )
@ -210,7 +211,7 @@ public final class BitWriteBuffer
/** /**
* Get a textual report on the bit-statistics * Get a textual report on the bit-statistics
* *
* @see #assignBits * @see #assignBits
*/ */
public static String getBitReport() public static String getBitReport()

View file

@ -10,7 +10,7 @@ import java.util.PriorityQueue;
* It detects identical sets and sorts them * It detects identical sets and sorts them
* into a huffman-tree according to their frequencies * into a huffman-tree according to their frequencies
* *
* Adapted for 3-pass encoding (counters -> statistics -> encoding ) * Adapted for 3-pass encoding (counters -&gt; statistics -&gt; encoding )
* but doesn't do anything at pass1 * but doesn't do anything at pass1
*/ */
public abstract class HuffmanTreeEncoder<V> public abstract class HuffmanTreeEncoder<V>
@ -124,10 +124,10 @@ public abstract class HuffmanTreeEncoder<V>
} }
} }
} }
@Override @Override
public boolean equals( Object o ) public boolean equals( Object o )
{ {
return itemEquals( ((TreeNode)o).data, data ); return itemEquals( ((TreeNode)o).data, data );
} }

View file

@ -10,7 +10,7 @@ import java.util.PriorityQueue;
* It detects identical sets and sorts them * It detects identical sets and sorts them
* into a huffman-tree according to their frequencies * into a huffman-tree according to their frequencies
* *
* Adapted for 3-pass encoding (counters -> statistics -> encoding ) * Adapted for 3-pass encoding (counters -&gt; statistics -&gt; encoding )
* but doesn't do anything at pass1 * but doesn't do anything at pass1
*/ */
public final class TagSetEncoder public final class TagSetEncoder
@ -131,7 +131,7 @@ public final class TagSetEncoder
} }
} }
} }
@Override @Override
public boolean equals( Object o ) public boolean equals( Object o )
{ {

View file

@ -635,7 +635,9 @@ public class BRouterView extends View
int lat = n.ilat - centerLat; int lat = n.ilat - centerLat;
int x = imgw / 2 + (int) ( scaleLon * lon ); int x = imgw / 2 + (int) ( scaleLon * lon );
int y = imgh / 2 - (int) ( scaleLat * lat ); int y = imgh / 2 - (int) ( scaleLat * lat );
int ir = (int) ( n.radius * 1000000. * scaleLat );
double[] lonlat2m = CheapRulerSingleton.getLonLatToMeterScales( centerLat );
int ir = (int) ( n.radius * scaleLat / lonlat2m[1]);
if ( ir > minradius ) if ( ir > minradius )
{ {
Paint paint = new Paint(); Paint paint = new Paint();
@ -660,7 +662,8 @@ public class BRouterView extends View
private void paintPolygon( Canvas canvas, OsmNogoPolygon p, int minradius ) private void paintPolygon( Canvas canvas, OsmNogoPolygon p, int minradius )
{ {
final int ir = (int) ( p.radius * 1000000. * scaleLat ); double[] lonlat2m = CheapRulerSingleton.getLonLatToMeterScales( centerLat );
final int ir = (int) ( p.radius * scaleLat / lonlat2m[1] );
if ( ir > minradius ) if ( ir > minradius )
{ {
Paint paint = new Paint(); Paint paint = new Paint();

View file

@ -13,11 +13,11 @@ import java.util.HashMap;
import java.util.List; import java.util.List;
/** /**
* URL query parameter handler for web and standalone server. Supports all * URL query parameter handler for web and standalone server. Supports all
* BRouter features without restrictions. * BRouter features without restrictions.
* *
* Parameters: * Parameters:
* *
* lonlats = lon,lat|... (unlimited list of lon,lat waypoints separated by |) * lonlats = lon,lat|... (unlimited list of lon,lat waypoints separated by |)
* nogos = lon,lat,radius|... (optional, radius in meters) * nogos = lon,lat,radius|... (optional, radius in meters)
* profile = profile file name without .brf * profile = profile file name without .brf
@ -25,8 +25,8 @@ import java.util.List;
* format = [kml|gpx|geojson] (optional, default gpx) * format = [kml|gpx|geojson] (optional, default gpx)
* *
* Example URLs: * Example URLs:
* http://localhost:17777/brouter?lonlats=8.799297,49.565883|8.811764,49.563606&nogos=&profile=trekking&alternativeidx=0&format=gpx * {@code http://localhost:17777/brouter?lonlats=8.799297,49.565883|8.811764,49.563606&nogos=&profile=trekking&alternativeidx=0&format=gpx}
* http://localhost:17777/brouter?lonlats=1.1,1.2|2.1,2.2|3.1,3.2|4.1,4.2&nogos=-1.1,-1.2,1|-2.1,-2.2,2&profile=shortest&alternativeidx=1&format=kml * {@code http://localhost:17777/brouter?lonlats=1.1,1.2|2.1,2.2|3.1,3.2|4.1,4.2&nogos=-1.1,-1.2,1|-2.1,-2.2,2&profile=shortest&alternativeidx=1&format=kml}
* *
*/ */
public class ServerHandler extends RequestHandler { public class ServerHandler extends RequestHandler {
@ -59,7 +59,7 @@ public class ServerHandler extends RequestHandler {
rc.localFunction = profile; rc.localFunction = profile;
rc.setAlternativeIdx(Integer.parseInt(params.get( "alternativeidx" ))); rc.setAlternativeIdx(Integer.parseInt(params.get( "alternativeidx" )));
List<OsmNodeNamed> nogoList = readNogoList(); List<OsmNodeNamed> nogoList = readNogoList();
List<OsmNodeNamed> nogoPolygonsList = readNogoPolygons(); List<OsmNodeNamed> nogoPolygonsList = readNogoPolygons();
@ -89,14 +89,14 @@ public class ServerHandler extends RequestHandler {
if (lonLats == null) throw new IllegalArgumentException( "lonlats parameter not set" ); if (lonLats == null) throw new IllegalArgumentException( "lonlats parameter not set" );
String[] coords = lonLats.split("\\|"); String[] coords = lonLats.split("\\|");
if (coords.length < 2) if (coords.length < 2)
throw new IllegalArgumentException( "we need two lat/lon points at least!" ); throw new IllegalArgumentException( "we need two lat/lon points at least!" );
List<OsmNodeNamed> wplist = new ArrayList<OsmNodeNamed>(); List<OsmNodeNamed> wplist = new ArrayList<OsmNodeNamed>();
for (int i = 0; i < coords.length; i++) for (int i = 0; i < coords.length; i++)
{ {
String[] lonLat = coords[i].split(","); String[] lonLat = coords[i].split(",");
if (lonLat.length < 2) if (lonLat.length < 2)
throw new IllegalArgumentException( "we need two lat/lon points at least!" ); throw new IllegalArgumentException( "we need two lat/lon points at least!" );
wplist.add( readPosition( lonLat[0], lonLat[1], "via" + i ) ); wplist.add( readPosition( lonLat[0], lonLat[1], "via" + i ) );
} }
@ -106,7 +106,7 @@ public class ServerHandler extends RequestHandler {
return wplist; return wplist;
} }
@Override @Override
public String formatTrack(OsmTrack track) public String formatTrack(OsmTrack track)
{ {
@ -175,7 +175,7 @@ public class ServerHandler extends RequestHandler {
result = "text/tab-separated-values"; result = "text/tab-separated-values";
} }
} }
return result; return result;
} }
@ -197,10 +197,10 @@ public class ServerHandler extends RequestHandler {
{ {
if ( vlon == null ) throw new IllegalArgumentException( "lon " + name + " not found in input" ); if ( vlon == null ) throw new IllegalArgumentException( "lon " + name + " not found in input" );
if ( vlat == null ) throw new IllegalArgumentException( "lat " + name + " not found in input" ); if ( vlat == null ) throw new IllegalArgumentException( "lat " + name + " not found in input" );
return readPosition(Double.parseDouble( vlon ), Double.parseDouble( vlat ), name); return readPosition(Double.parseDouble( vlon ), Double.parseDouble( vlat ), name);
} }
private static OsmNodeNamed readPosition( double lon, double lat, String name ) private static OsmNodeNamed readPosition( double lon, double lat, String name )
{ {
OsmNodeNamed n = new OsmNodeNamed(); OsmNodeNamed n = new OsmNodeNamed();
@ -209,7 +209,7 @@ public class ServerHandler extends RequestHandler {
n.ilat = (int)( ( lat + 90. ) *1000000. + 0.5); n.ilat = (int)( ( lat + 90. ) *1000000. + 0.5);
return n; return n;
} }
private List<OsmNodeNamed> readNogoList() private List<OsmNodeNamed> readNogoList()
{ {
// lon,lat,radius|... // lon,lat,radius|...
@ -227,7 +227,7 @@ public class ServerHandler extends RequestHandler {
return nogoList; return nogoList;
} }
private static OsmNodeNamed readNogo( String lon, String lat, String radius ) private static OsmNodeNamed readNogo( String lon, String lat, String radius )
{ {
return readNogo(Double.parseDouble( lon ), Double.parseDouble( lat ), Integer.parseInt( radius ) ); return readNogo(Double.parseDouble( lon ), Double.parseDouble( lat ), Integer.parseInt( radius ) );
@ -250,7 +250,7 @@ public class ServerHandler extends RequestHandler {
parseNogoPolygons( params.get("polygons"), result, true ); parseNogoPolygons( params.get("polygons"), result, true );
return result.size() > 0 ? result : null; return result.size() > 0 ? result : null;
} }
private static void parseNogoPolygons(String polygons, List<OsmNodeNamed> result, boolean closed ) private static void parseNogoPolygons(String polygons, List<OsmNodeNamed> result, boolean closed )
{ {
if ( polygons != null ) if ( polygons != null )
@ -277,6 +277,6 @@ public class ServerHandler extends RequestHandler {
} }
} }
} }
} }
} }
} }

View file

@ -15,13 +15,13 @@ public class BitCoderContext
this.ab = ab; this.ab = ab;
idxMax = ab.length-1; idxMax = ab.length-1;
} }
public final void reset( byte[] ab ) public final void reset( byte[] ab )
{ {
this.ab = ab; this.ab = ab;
idxMax = ab.length-1; idxMax = ab.length-1;
reset(); reset();
} }
public final void reset() public final void reset()
{ {
@ -29,16 +29,16 @@ public class BitCoderContext
bm = 0x100; bm = 0x100;
bits = 0; bits = 0;
b = 0; b = 0;
} }
/** /**
* encode a distance with a variable bit length * encode a distance with a variable bit length
* (poor mans huffman tree) * (poor mans huffman tree)
* 1 -> 0 * {@code 1 -> 0}
* 01 -> 1 + following 1-bit word ( 1..2 ) * {@code 01 -> 1} + following 1-bit word ( 1..2 )
* 001 -> 3 + following 2-bit word ( 3..6 ) * {@code 001 -> 3} + following 2-bit word ( 3..6 )
* 0001 -> 7 + following 3-bit word ( 7..14 ) etc. * {@code 0001 -> 7} + following 3-bit word ( 7..14 ) etc.
* *
* @see #decodeVarBits * @see #decodeVarBits
*/ */
public final void encodeVarBits( int value ) public final void encodeVarBits( int value )
@ -175,7 +175,7 @@ public class BitCoderContext
bits -= count; bits -= count;
return value; return value;
} }
private void fillBuffer() private void fillBuffer()
{ {
while (bits < 24) while (bits < 24)
@ -186,7 +186,7 @@ public class BitCoderContext
} }
bits += 8; bits += 8;
} }
} }
/** /**
* @return the encoded length in bytes * @return the encoded length in bytes

View file

@ -17,7 +17,7 @@ public final class ByteArrayUnifier implements IByteArrayUnifier
* Unify a byte array in order to reuse instances when possible. * Unify a byte array in order to reuse instances when possible.
* The byte arrays are assumed to be treated as immutable, * The byte arrays are assumed to be treated as immutable,
* allowing the reuse * allowing the reuse
* @param the byte array to unify * @param ab the byte array to unify
* @return the cached instance or the input instanced if not cached * @return the cached instance or the input instanced if not cached
*/ */
public byte[] unify( byte[] ab ) public byte[] unify( byte[] ab )

View file

@ -17,10 +17,10 @@ public final class CheapRulerSingleton {
public final static int KILOMETERS_TO_METERS = 1000; public final static int KILOMETERS_TO_METERS = 1000;
public final static double DEG_TO_RAD = Math.PI / 180.; public final static double DEG_TO_RAD = Math.PI / 180.;
// Cosine cache constants // Scale cache constants
private final static int SCALE_CACHE_LENGTH = 1800; private final static int SCALE_CACHE_LENGTH = 1800;
private final static int SCALE_CACHE_INCREMENT = 100000; private final static int SCALE_CACHE_INCREMENT = 100000;
// COS_CACHE_LENGTH cached values between 0 and COS_CACHE_MAX_DEGREES degrees. // SCALE_CACHE_LENGTH cached values between 0 and COS_CACHE_MAX_DEGREES degrees.
private final static double[][] SCALE_CACHE = new double[SCALE_CACHE_LENGTH][]; private final static double[][] SCALE_CACHE = new double[SCALE_CACHE_LENGTH][];
/** /**
@ -33,7 +33,7 @@ public final class CheapRulerSingleton {
} }
private static double[] calcKxKyFromILat(int ilat) { private static double[] calcKxKyFromILat(int ilat) {
double lat = DEG_TO_RAD*(ilat-90000000)/1000000.; double lat = DEG_TO_RAD*ilat*ILATLNG_TO_LATLNG - 90;
double cos = Math.cos(lat); double cos = Math.cos(lat);
double cos2 = 2 * cos * cos - 1; double cos2 = 2 * cos * cos - 1;
double cos3 = 2 * cos * cos2 - cos; double cos3 = 2 * cos * cos2 - cos;
@ -49,9 +49,9 @@ public final class CheapRulerSingleton {
} }
/** /**
* Calculate the degree->meter scale for given latitude * Calculate the degree-&gt;meter scale for given latitude
* *
* @result [lon->meter,lat->meter] * @return [lon-&gt;meter,lat-&gt;meter]
*/ */
public static double[] getLonLatToMeterScales( int ilat ) { public static double[] getLonLatToMeterScales( int ilat ) {
return SCALE_CACHE[ ilat / SCALE_CACHE_INCREMENT ]; return SCALE_CACHE[ ilat / SCALE_CACHE_INCREMENT ];
@ -65,12 +65,14 @@ public final class CheapRulerSingleton {
* @param ilat1 Integer latitude for the start point, this is (latitude + 90) * 1e6. * @param ilat1 Integer latitude for the start point, this is (latitude + 90) * 1e6.
* @param ilon2 Integer longitude for the end point, this is (longitude + 180) * 1e6. * @param ilon2 Integer longitude for the end point, this is (longitude + 180) * 1e6.
* @param ilat2 Integer latitude for the end point, this is (latitude + 90) * 1e6. * @param ilat2 Integer latitude for the end point, this is (latitude + 90) * 1e6.
* @return The distance between the two points, in meters.
* *
* @note Integer longitude is ((longitude in degrees) + 180) * 1e6. * Note:
* Integer latitude is ((latitude in degrees) + 90) * 1e6. * Integer longitude is ((longitude in degrees) + 180) * 1e6.
* Integer latitude is ((latitude in degrees) + 90) * 1e6.
*/ */
public static double distance(int ilon1, int ilat1, int ilon2, int ilat2) { public static double distance(int ilon1, int ilat1, int ilon2, int ilat2) {
double[] kxky = getLonLatToMeterScales( ( ilat1 + ilat2 ) >> 1 ); double[] kxky = getLonLatToMeterScales( ( ilat1 + ilat2 ) >> 1 );
double dlon = (ilon1 - ilon2) * kxky[0]; double dlon = (ilon1 - ilon2) * kxky[0];
double dlat = (ilat1 - ilat2) * kxky[1]; double dlat = (ilat1 - ilat2) * kxky[1];
return Math.sqrt(dlat * dlat + dlon * dlon); // in m return Math.sqrt(dlat * dlat + dlon * dlon); // in m

View file

@ -31,8 +31,6 @@ public class DenseLongMap
* Creates a DenseLongMap for the default block size * Creates a DenseLongMap for the default block size
* ( 512 bytes per bitplane, covering a key range of 4096 keys ) * ( 512 bytes per bitplane, covering a key range of 4096 keys )
* Note that one value range is limited to 0..254 * Note that one value range is limited to 0..254
*
* @param valuebits number of bits to use per value
*/ */
public DenseLongMap() public DenseLongMap()
{ {
@ -85,7 +83,7 @@ public class DenseLongMap
while (blocklist.size() < blockn+1 ) while (blocklist.size() < blockn+1 )
{ {
blocklist.add(null); blocklist.add(null);
} }
blocklist.set( blockn, block ); blocklist.set( blockn, block );
} }
else else
@ -99,7 +97,7 @@ public class DenseLongMap
int headersize = 1 << valuebits; int headersize = 1 << valuebits;
byte v = (byte)(value + 1); // 0 is reserved (=unset) byte v = (byte)(value + 1); // 0 is reserved (=unset)
// find the index in the lookup table or the first entry // find the index in the lookup table or the first entry
int idx = 1; int idx = 1;
while( idx < headersize ) while( idx < headersize )
@ -122,7 +120,7 @@ public class DenseLongMap
valuebits++; valuebits++;
headersize = 1 << valuebits; headersize = 1 << valuebits;
} }
int bitmask = 1 << (offset & 0x7); int bitmask = 1 << (offset & 0x7);
int invmask = bitmask ^ 0xff; int invmask = bitmask ^ 0xff;
int probebit = 1; int probebit = 1;
@ -149,7 +147,7 @@ public class DenseLongMap
// size is lookup table + datablocks // size is lookup table + datablocks
return ( 1 << bits ) + blocksize * bits; return ( 1 << bits ) + blocksize * bits;
} }
private byte[] expandBlock( byte[] block, int valuebits ) private byte[] expandBlock( byte[] block, int valuebits )
{ {
bitplaneCount[valuebits] ++; bitplaneCount[valuebits] ++;
@ -204,7 +202,7 @@ public class DenseLongMap
{ {
return -1; return -1;
} }
// check how many bitplanes we have from the arrayzize // check how many bitplanes we have from the arrayzize
int valuebits = 1; int valuebits = 1;
while( sizeForBits( valuebits) < block.length ) while( sizeForBits( valuebits) < block.length )
@ -212,7 +210,7 @@ public class DenseLongMap
valuebits++; valuebits++;
} }
int headersize = 1 << valuebits; int headersize = 1 << valuebits;
int bitmask = 1 << (offset & 7); int bitmask = 1 << (offset & 7);
int probebit = 1; int probebit = 1;
int blockidx = (offset >> 3) + headersize; int blockidx = (offset >> 3) + headersize;

View file

@ -4,7 +4,7 @@ import java.util.Random;
/** /**
* Memory efficient and lightning fast heap to get the lowest-key value of a set of key-object pairs * Memory efficient and lightning fast heap to get the lowest-key value of a set of key-object pairs
* *
* @author ab * @author ab
*/ */
public final class SortedHeap<V> public final class SortedHeap<V>
@ -54,7 +54,7 @@ public final class SortedHeap<V>
Object[] vla; // value array Object[] vla; // value array
int lv; // low value int lv; // low value
int lp; // low pointer int lp; // low pointer
SortedBin( int binsize, SortedHeap parent ) SortedBin( int binsize, SortedHeap parent )
{ {
this.binsize = binsize; this.binsize = binsize;
@ -63,7 +63,7 @@ public final class SortedHeap<V>
vla = new Object[binsize]; vla = new Object[binsize];
lp = binsize; lp = binsize;
} }
SortedBin next() SortedBin next()
{ {
if ( next == null ) if ( next == null )
@ -108,7 +108,7 @@ public final class SortedHeap<V>
neBin = next; neBin = next;
} }
} }
void add( int key, Object value ) void add( int key, Object value )
{ {
int p = lp; int p = lp;
@ -126,17 +126,15 @@ public final class SortedHeap<V>
p++; p++;
} }
} }
} }
/** /**
* add a key value pair to the heap * add a key value pair to the heap
* *
* @param id * @param key the key to insert
* the key to insert * @param value the value to insert object
* @param value
* the value to insert object
*/ */
public void add( int key, V value ) public void add( int key, V value )
{ {
@ -164,16 +162,16 @@ public final class SortedHeap<V>
first.nextNonEmpty = second; first.nextNonEmpty = second;
} }
} }
} }
private void sortUp() private void sortUp()
{ {
if ( size > peaksize ) if ( size > peaksize )
{ {
peaksize = size; peaksize = size;
} }
// determine the first array big enough to take them all // determine the first array big enough to take them all
int cnt = 8; // value count of first 2 bins is always 8 int cnt = 8; // value count of first 2 bins is always 8
SortedBin tbin = second; // target bin SortedBin tbin = second; // target bin
@ -193,10 +191,10 @@ public final class SortedHeap<V>
int[] al_t = tbin.al; int[] al_t = tbin.al;
Object[] vla_t = tbin.vla; Object[] vla_t = tbin.vla;
int tp = tbin.binsize-cnt; // target pointer int tp = tbin.binsize-cnt; // target pointer
// unlink any higher, non-empty arrays // unlink any higher, non-empty arrays
SortedBin otherNonEmpty = lastNonEmpty.nextNonEmpty; SortedBin otherNonEmpty = lastNonEmpty.nextNonEmpty;
lastNonEmpty.nextNonEmpty = null; lastNonEmpty.nextNonEmpty = null;
// now merge the content of these non-empty bins into the target bin // now merge the content of these non-empty bins into the target bin
while( firstNonEmpty != null ) while( firstNonEmpty != null )
@ -215,7 +213,7 @@ public final class SortedHeap<V>
} }
// current minimum found, copy to target array // current minimum found, copy to target array
al_t[tp] = minId; al_t[tp] = minId;
vla_t[tp++] = minBin.dropLowest(); vla_t[tp++] = minBin.dropLowest();
} }
@ -233,7 +231,7 @@ public final class SortedHeap<V>
second = new SortedBin( 4, this ); second = new SortedBin( 4, this );
firstNonEmpty = null; firstNonEmpty = null;
} }
public int getSize() public int getSize()
{ {
return size; return size;
@ -267,7 +265,7 @@ public final class SortedHeap<V>
} }
return tp; return tp;
} }
public static void main(String[] args) public static void main(String[] args)
{ {
SortedHeap<String> sh = new SortedHeap<String>(); SortedHeap<String> sh = new SortedHeap<String>();
@ -296,6 +294,6 @@ System.out.println( "popLowestKeyValue: " + val);
// Assert.assertTrue( "total count test", cnt == 100000 ); // Assert.assertTrue( "total count test", cnt == 100000 );
} }
} }