map access layer cleanup
This commit is contained in:
parent
2cec35f3cc
commit
f8dee5b7d1
7 changed files with 163 additions and 150 deletions
|
@ -109,7 +109,7 @@ 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 class: " + link.getClass() );
|
||||
if ( link.descriptionBitmap == null ) throw new IllegalArgumentException( "null description for: " + link );
|
||||
|
||||
boolean recordTransferNodes = detailMode || rc.countTraffic;
|
||||
boolean recordMessageData = detailMode;
|
||||
|
|
|
@ -381,7 +381,7 @@ public class RoutingEngine extends Thread
|
|||
{
|
||||
continue;
|
||||
}
|
||||
expandHollowLinkTargets( n, false );
|
||||
expandHollowLinkTargets( n );
|
||||
OsmLink startLink = new OsmLink();
|
||||
startLink.targetNode = n;
|
||||
OsmPath startPath = new OsmPath( startLink );
|
||||
|
@ -418,30 +418,12 @@ public class RoutingEngine extends Thread
|
|||
}
|
||||
|
||||
// expand hollow link targets and resolve reverse links
|
||||
private void expandHollowLinkTargets( OsmNode n, boolean failOnReverseNotFound )
|
||||
private void expandHollowLinkTargets( OsmNode n )
|
||||
{
|
||||
for( OsmLink link = n.firstlink; link != null; link = link.next )
|
||||
{
|
||||
if ( ! nodesCache.obtainNonHollowNode( link.targetNode ) )
|
||||
{
|
||||
continue;
|
||||
nodesCache.obtainNonHollowNode( link.targetNode );
|
||||
}
|
||||
|
||||
if ( link.counterLinkWritten )
|
||||
{
|
||||
OsmLink rlink = link.targetNode.getReverseLink( n.getILon(), n.getILat() );
|
||||
if ( rlink == null )
|
||||
{
|
||||
if ( failOnReverseNotFound ) throw new RuntimeException( "reverse link not found!" );
|
||||
}
|
||||
else
|
||||
{
|
||||
link.descriptionBitmap = rlink.descriptionBitmap;
|
||||
link.firsttransferBytes = rlink.firsttransferBytes;
|
||||
}
|
||||
}
|
||||
}
|
||||
n.wasProcessed = true;
|
||||
}
|
||||
|
||||
private OsmTrack searchTrack( MatchedWaypoint startWp, MatchedWaypoint endWp, OsmTrack nearbyTrack, OsmTrack refTrack )
|
||||
|
@ -541,7 +523,7 @@ public class RoutingEngine extends Thread
|
|||
{
|
||||
return null;
|
||||
}
|
||||
expandHollowLinkTargets( start, true );
|
||||
expandHollowLinkTargets( start );
|
||||
return start;
|
||||
}
|
||||
|
||||
|
@ -804,10 +786,7 @@ public class RoutingEngine extends Thread
|
|||
continue;
|
||||
}
|
||||
|
||||
if ( !currentNode.wasProcessed )
|
||||
{
|
||||
expandHollowLinkTargets( currentNode, true );
|
||||
}
|
||||
expandHollowLinkTargets( currentNode );
|
||||
|
||||
if ( sourceNode != null )
|
||||
{
|
||||
|
|
|
@ -26,6 +26,7 @@ public final class BExpressionMetaData
|
|||
private static final String CONTEXT_TAG = "---context:";
|
||||
private static final String VERSION_TAG = "---lookupversion:";
|
||||
private static final String MINOR_VERSION_TAG = "---minorversion:";
|
||||
private static final String VARLENGTH_TAG = "---readvarlength";
|
||||
|
||||
public short lookupVersion = -1;
|
||||
public short lookupMinorVersion = -1;
|
||||
|
@ -66,6 +67,10 @@ public final class BExpressionMetaData
|
|||
lookupMinorVersion = Short.parseShort( line.substring( MINOR_VERSION_TAG.length() ) );
|
||||
continue;
|
||||
}
|
||||
if ( line.startsWith( VARLENGTH_TAG ) ) // tag removed...
|
||||
{
|
||||
continue;
|
||||
}
|
||||
if ( ctx != null ) ctx.parseMetaLine( line );
|
||||
}
|
||||
br.close();
|
||||
|
|
|
@ -14,7 +14,7 @@ import btools.util.Crc32;
|
|||
|
||||
final class MicroCache extends ByteDataReader
|
||||
{
|
||||
private long[] faid;
|
||||
private int[] faid;
|
||||
private int[] fapos;
|
||||
private int size = 0;
|
||||
private int delcount = 0;
|
||||
|
@ -24,6 +24,9 @@ final class MicroCache extends ByteDataReader
|
|||
// the object parsing position and length
|
||||
private int aboffsetEnd;
|
||||
|
||||
private int lonIdxBase;
|
||||
private int latIdxBase;
|
||||
|
||||
// cache control: a virgin cache can be
|
||||
// put to ghost state for later recovery
|
||||
boolean virgin = true;
|
||||
|
@ -35,8 +38,8 @@ final class MicroCache extends ByteDataReader
|
|||
int lonDegree = lonIdx80/80;
|
||||
int latDegree = latIdx80/80;
|
||||
|
||||
int lonIdxBase = (lonIdx80/5)*62500 + 31250;
|
||||
int latIdxBase = (latIdx80/5)*62500 + 31250;
|
||||
lonIdxBase = (lonIdx80/5)*62500 + 31250;
|
||||
latIdxBase = (latIdx80/5)*62500 + 31250;
|
||||
|
||||
int subIdx = (latIdx80-80*latDegree)*80 + (lonIdx80-80*lonDegree);
|
||||
|
||||
|
@ -61,8 +64,7 @@ final class MicroCache extends ByteDataReader
|
|||
int nbytes = 0;
|
||||
for(int i = 0; i<size; i++)
|
||||
{
|
||||
int ilon = readShort();
|
||||
int ilat = readShort();
|
||||
aboffset += 4;
|
||||
int bodySize = readVarLengthUnsigned();
|
||||
|
||||
aboffset += bodySize;
|
||||
|
@ -79,20 +81,15 @@ final class MicroCache extends ByteDataReader
|
|||
byte[] nab = new byte[nbytes];
|
||||
aboffset = 4;
|
||||
int noffset = 0;
|
||||
faid = new long[size];
|
||||
faid = new int[size];
|
||||
fapos = new int[size];
|
||||
p2size = 0x40000000;
|
||||
while( p2size > size ) p2size >>= 1;
|
||||
|
||||
for(int i = 0; i<size; i++)
|
||||
{
|
||||
int ilon = readShort();
|
||||
int ilat = readShort();
|
||||
ilon += lonIdxBase;
|
||||
ilat += latIdxBase;
|
||||
long nodeId = ((long)ilon)<<32 | ilat;
|
||||
faid[i] = readInt() ^ 0x8000; // flip lat-sign for correct ordering
|
||||
|
||||
faid[i] = nodeId;
|
||||
int bodySize = readVarLengthUnsigned();
|
||||
fapos[i] = noffset;
|
||||
System.arraycopy( ab, aboffset, nab, noffset, bodySize );
|
||||
|
@ -123,13 +120,14 @@ final class MicroCache extends ByteDataReader
|
|||
* Throws an exception if that id was already requested
|
||||
* as an early detector for identity problems
|
||||
*/
|
||||
private boolean getAndClear( long id )
|
||||
private boolean getAndClear( long id64 )
|
||||
{
|
||||
if ( size == 0 )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
long[] a = faid;
|
||||
int id = shrinkId( id64 );
|
||||
int[] a = faid;
|
||||
int offset = p2size;
|
||||
int n = 0;
|
||||
|
||||
|
@ -194,7 +192,7 @@ final class MicroCache extends ByteDataReader
|
|||
}
|
||||
else
|
||||
{
|
||||
long[] nfaid = new long[nsize];
|
||||
int[] nfaid = new int[nsize];
|
||||
int[] nfapos = new int[nsize];
|
||||
int idx = 0;
|
||||
|
||||
|
@ -242,14 +240,30 @@ final class MicroCache extends ByteDataReader
|
|||
|
||||
for( int i=0; i<size; i++ )
|
||||
{
|
||||
OsmNode n = new OsmNode( faid[i] );
|
||||
int id32 = faid[i];
|
||||
long id64 = expandId( id32 );
|
||||
OsmNode n = new OsmNode( id64 );
|
||||
n.setHollow();
|
||||
nodesMap.put( faid[i], n );
|
||||
nodesMap.put( n );
|
||||
positions.add( n );
|
||||
}
|
||||
return positions;
|
||||
}
|
||||
|
||||
private long expandId( int id32 )
|
||||
{
|
||||
int lon32 = lonIdxBase + (short)(id32 >> 16);
|
||||
int lat32 = latIdxBase + (short)((id32 & 0xffff) ^ 0x8000);
|
||||
return ((long)lon32)<<32 | lat32;
|
||||
}
|
||||
|
||||
private int shrinkId( long id64 )
|
||||
{
|
||||
int lon32 = (int)(id64 >> 32);
|
||||
int lat32 = (int)(id64 & 0xffffffff);
|
||||
return (lon32 - lonIdxBase)<<16 | ( ( (lat32 - latIdxBase) & 0xffff) ^ 0x8000);
|
||||
}
|
||||
|
||||
public boolean hasMoreData()
|
||||
{
|
||||
return aboffset < aboffsetEnd;
|
||||
|
|
|
@ -19,12 +19,6 @@ public class OsmLink
|
|||
*/
|
||||
public OsmNode targetNode;
|
||||
|
||||
/**
|
||||
* The origin position
|
||||
*/
|
||||
public int ilatOrigin;
|
||||
public int ilonOrigin;
|
||||
|
||||
public OsmLink next;
|
||||
|
||||
public byte[] firsttransferBytes;
|
||||
|
@ -42,6 +36,8 @@ public class OsmLink
|
|||
|
||||
public boolean counterLinkWritten;
|
||||
|
||||
public byte state;
|
||||
|
||||
public OsmLinkHolder firstlinkholder = null;
|
||||
|
||||
final public void addLinkHolder( OsmLinkHolder holder )
|
||||
|
@ -49,4 +45,9 @@ public class OsmLink
|
|||
if ( firstlinkholder != null ) { holder.setNextForLink( firstlinkholder ); }
|
||||
firstlinkholder = holder;
|
||||
}
|
||||
|
||||
public String toString()
|
||||
{
|
||||
return "Link(target=" + targetNode.getIdFromPos() + " counterLinkWritten=" + counterLinkWritten + " state=" + state + ")";
|
||||
}
|
||||
}
|
||||
|
|
|
@ -81,15 +81,51 @@ public class OsmNode implements OsmPos
|
|||
*/
|
||||
public OsmLink firstlink = null;
|
||||
|
||||
public OsmLink firstreverse = null;
|
||||
|
||||
public boolean wasProcessed; // whether this node has all it's links resolved
|
||||
|
||||
// preliminry in forward order to avoid regressions
|
||||
public void addLink( OsmLink link )
|
||||
{
|
||||
if ( firstlink != null ) link.next = firstlink;
|
||||
if ( firstlink == null )
|
||||
{
|
||||
firstlink = link;
|
||||
}
|
||||
else
|
||||
{
|
||||
OsmLink l = firstlink;
|
||||
while( l.next != null ) l = l.next;
|
||||
l.next = link;
|
||||
}
|
||||
}
|
||||
|
||||
private OsmLink getCompatibleLink( int ilon, int ilat, boolean counterLinkWritten, int state )
|
||||
{
|
||||
for( OsmLink l = firstlink; l != null; l = l.next )
|
||||
{
|
||||
if ( counterLinkWritten == l.counterLinkWritten && l.state == state )
|
||||
{
|
||||
OsmNode t = l.targetNode;
|
||||
if ( t.ilon == ilon && t.ilat == ilat )
|
||||
{
|
||||
l.state = 0;
|
||||
return l;
|
||||
}
|
||||
}
|
||||
}
|
||||
// second try ignoring counterLinkWritten
|
||||
// (border links are written in both directions)
|
||||
for( OsmLink l = firstlink; l != null; l = l.next )
|
||||
{
|
||||
if ( l.state == state )
|
||||
{
|
||||
OsmNode t = l.targetNode;
|
||||
if ( t.ilon == ilon && t.ilat == ilat )
|
||||
{
|
||||
l.state = 0;
|
||||
return l;
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public int calcDistance( OsmPos p )
|
||||
{
|
||||
|
@ -104,6 +140,10 @@ public class OsmNode implements OsmPos
|
|||
return (int)(d + 1.0 );
|
||||
}
|
||||
|
||||
public String toString()
|
||||
{
|
||||
return "" + getIdFromPos();
|
||||
}
|
||||
|
||||
public void parseNodeBody( MicroCache is, OsmNodesMap hollowNodes, DistanceChecker dc )
|
||||
{
|
||||
|
@ -111,17 +151,12 @@ public class OsmNode implements OsmPos
|
|||
|
||||
selev = is.readShort();
|
||||
|
||||
OsmLink lastlink = null;
|
||||
|
||||
OsmLink firstHollowLink = firstlink;
|
||||
firstlink = null;
|
||||
|
||||
while( is.hasMoreData() )
|
||||
{
|
||||
int ilonref = ilon;
|
||||
int ilatref = ilat;
|
||||
|
||||
OsmLink link = new OsmLink();
|
||||
boolean counterLinkWritten = false;
|
||||
OsmTransferNode firstTransferNode = null;
|
||||
OsmTransferNode lastTransferNode = null;
|
||||
int linklon;
|
||||
|
@ -163,10 +198,10 @@ public class OsmNode implements OsmPos
|
|||
}
|
||||
if ( (bitField & SKIPDETAILS_BITMASK ) != 0 )
|
||||
{
|
||||
link.counterLinkWritten = true;
|
||||
counterLinkWritten = true;
|
||||
}
|
||||
|
||||
if ( description == null && !link.counterLinkWritten ) throw new IllegalArgumentException( "internal error: missing way description!" );
|
||||
if ( description == null && !counterLinkWritten ) throw new IllegalArgumentException( "internal error: missing way description!" );
|
||||
|
||||
boolean isTransfer = (bitField & TRANSFERNODE_BITMASK ) != 0;
|
||||
if ( isTransfer )
|
||||
|
@ -188,17 +223,16 @@ public class OsmNode implements OsmPos
|
|||
}
|
||||
else
|
||||
{
|
||||
link.descriptionBitmap = description;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// performance shortcut: ignore link if out of reach
|
||||
if ( dc != null && !link.counterLinkWritten )
|
||||
if ( dc != null && !counterLinkWritten )
|
||||
{
|
||||
if ( !dc.isWithinRadius( ilon, ilat, firstTransferNode, linklon, linklat ) )
|
||||
{
|
||||
// continue;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -207,57 +241,46 @@ public class OsmNode implements OsmPos
|
|||
continue; // skip self-ref
|
||||
}
|
||||
|
||||
if ( lastlink == null )
|
||||
{
|
||||
firstlink = link;
|
||||
}
|
||||
else
|
||||
{
|
||||
lastlink.next = link;
|
||||
}
|
||||
lastlink = link;
|
||||
|
||||
OsmNode tn = null;
|
||||
|
||||
// first check the hollow links for that target
|
||||
for( OsmLink l = firstHollowLink; l != null; l = l.next )
|
||||
{
|
||||
OsmNode t = l.targetNode;
|
||||
if ( t.ilon == linklon && t.ilat == linklat )
|
||||
{
|
||||
tn = t;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if ( tn == null ) // then check the hollow-nodes
|
||||
// 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;
|
||||
tn = hollowNodes.get( targetNodeId ); // target node
|
||||
|
||||
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( targetNodeId, tn );
|
||||
}
|
||||
|
||||
OsmLink hollowLink = new OsmLink();
|
||||
hollowLink.targetNode = this;
|
||||
tn.addLink( hollowLink ); // make us known at the hollow link
|
||||
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);
|
||||
|
||||
// compute the reverse link
|
||||
if ( !link.counterLinkWritten )
|
||||
// .. and the reverse
|
||||
if ( rlink.counterLinkWritten )
|
||||
{
|
||||
OsmLink rlink = new OsmLink();
|
||||
byte[] linkDescriptionBitmap = link.descriptionBitmap;
|
||||
rlink.ilonOrigin = tn.ilon;
|
||||
rlink.ilatOrigin = tn.ilat;
|
||||
rlink.targetNode = this;
|
||||
rlink.descriptionBitmap = linkDescriptionBitmap; // default for no transfer-nodes
|
||||
rlink.descriptionBitmap = description; // default for no transfer-nodes
|
||||
OsmTransferNode previous = null;
|
||||
OsmTransferNode rtrans = null;
|
||||
for( OsmTransferNode trans = firstTransferNode; trans != null; trans = trans.next )
|
||||
|
@ -275,17 +298,18 @@ public class OsmNode implements OsmPos
|
|||
rtrans.ilat = trans.ilat;
|
||||
rtrans.selev = trans.selev;
|
||||
rtrans.next = previous;
|
||||
rtrans.descriptionBitmap = linkDescriptionBitmap;
|
||||
rtrans.descriptionBitmap = description;
|
||||
previous = rtrans;
|
||||
}
|
||||
rlink.encodeFirsttransfer(rtrans);
|
||||
rlink.next = firstreverse;
|
||||
firstreverse = rlink;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
hollowNodes.remove( getIdFromPos() );
|
||||
if ( dc == null )
|
||||
{
|
||||
hollowNodes.remove( this );
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isHollow()
|
||||
|
@ -320,34 +344,20 @@ public class OsmNode implements OsmPos
|
|||
}
|
||||
}
|
||||
|
||||
public OsmLink getReverseLink( int lon, int lat )
|
||||
@Override
|
||||
public boolean equals( Object o )
|
||||
{
|
||||
for( OsmLink rlink = firstreverse; rlink != null; rlink = rlink.next )
|
||||
if ( o instanceof OsmNode )
|
||||
{
|
||||
if ( rlink.ilonOrigin == lon && rlink.ilatOrigin == lat )
|
||||
{
|
||||
unlinkRLink( rlink );
|
||||
return rlink;
|
||||
OsmNode n = (OsmNode)o;
|
||||
return n.ilon == ilon && n.ilat == ilat;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
return false;
|
||||
}
|
||||
|
||||
public void unlinkRLink( OsmLink rlink )
|
||||
@Override
|
||||
public int hashCode( )
|
||||
{
|
||||
if ( rlink == firstreverse )
|
||||
{
|
||||
firstreverse = rlink.next;
|
||||
return;
|
||||
return ilon + ilat;
|
||||
}
|
||||
for( OsmLink l = firstreverse; l != null; l = l.next )
|
||||
{
|
||||
if ( l.next == rlink )
|
||||
{
|
||||
l.next = rlink.next;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -11,10 +11,12 @@ import btools.util.ByteArrayUnifier;
|
|||
|
||||
public final class OsmNodesMap
|
||||
{
|
||||
private HashMap<Long,OsmNode> hmap = new HashMap<Long,OsmNode>();
|
||||
private HashMap<OsmNode,OsmNode> hmap = new HashMap<OsmNode,OsmNode>();
|
||||
|
||||
private ByteArrayUnifier abUnifier = new ByteArrayUnifier( 16384, false );
|
||||
|
||||
private OsmNode testKey = new OsmNode();
|
||||
|
||||
public ByteArrayUnifier getByteArrayUnifier()
|
||||
{
|
||||
return abUnifier;
|
||||
|
@ -26,22 +28,24 @@ public final class OsmNodesMap
|
|||
*/
|
||||
public OsmNode get( long id )
|
||||
{
|
||||
return hmap.get( new Long( id ) );
|
||||
testKey.ilon = (int)(id >> 32);
|
||||
testKey.ilat = (int)(id & 0xffffffff);
|
||||
return hmap.get( testKey );
|
||||
}
|
||||
|
||||
|
||||
public void remove( long id )
|
||||
public void remove( OsmNode node )
|
||||
{
|
||||
hmap.remove( new Long( id ) );
|
||||
hmap.remove( node );
|
||||
}
|
||||
|
||||
/**
|
||||
* Put a node into the map
|
||||
* @return the previous node if that id existed, else null
|
||||
*/
|
||||
public OsmNode put( long id, OsmNode node )
|
||||
public OsmNode put( OsmNode node )
|
||||
{
|
||||
return hmap.put( new Long( id ), node );
|
||||
return hmap.put( node, node );
|
||||
}
|
||||
|
||||
|
||||
|
|
Loading…
Reference in a new issue