diff --git a/brouter-core/src/main/java/btools/router/OsmPath.java b/brouter-core/src/main/java/btools/router/OsmPath.java index e8fdf2d..fe8da57 100644 --- a/brouter-core/src/main/java/btools/router/OsmPath.java +++ b/brouter-core/src/main/java/btools/router/OsmPath.java @@ -103,7 +103,6 @@ final class OsmPath implements OsmLinkHolder OsmTransferNode transferNode = link.decodeFirsttransfer(); OsmNode targetNode = link.targetNode; - byte[] lastDescription = null; String lastMessage = null; for(;;) { @@ -132,15 +131,17 @@ final class OsmPath implements OsmLinkHolder 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( link.counterLinkWritten, description, rc.messageHandler ); + // if way description changed, store message - if ( lastMessage != null && description != lastDescription ) + if ( lastMessage != null && !sameData ) { originElement.message = lastMessage; linkdist = 0; linkelevationcost = 0; linkturncost = 0; } - lastDescription = description; int dist = rc.calcDistance( lon1, lat1, lon2, lat2 ); int elefactor = 250000; @@ -176,8 +177,6 @@ final class OsmPath implements OsmLinkHolder linkdist += dist; linkdisttotal += dist; - rc.messageHandler.setCurrentPos( lon2, lat2 ); - rc.expctxWay.evaluate( link instanceof OsmLinkReverse, description, rc.messageHandler ); // *** penalty for way-change if ( origin.originElement != null ) @@ -261,7 +260,7 @@ final class OsmPath implements OsmLinkHolder + iCost + "\t" + linkelevationcost + "\t" + linkturncost - + rc.expctxWay.getCsvDescription( description ); + + rc.expctxWay.getCsvDescription( link.counterLinkWritten, description ); } if ( stopAtEndpoint ) diff --git a/brouter-core/src/main/java/btools/router/RoutingEngine.java b/brouter-core/src/main/java/btools/router/RoutingEngine.java index cd6574e..13d7187 100644 --- a/brouter-core/src/main/java/btools/router/RoutingEngine.java +++ b/brouter-core/src/main/java/btools/router/RoutingEngine.java @@ -296,7 +296,7 @@ public class RoutingEngine extends Thread startLink.addLinkHolder( startPath ); for( OsmLink link = n.firstlink; link != null; link = link.next ) { - if ( link.counterLinkWritten ) continue; // reverse link not found + 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 @@ -346,7 +346,6 @@ public class RoutingEngine extends Thread { link.descriptionBitmap = rlink.descriptionBitmap; link.firsttransferBytes = rlink.firsttransferBytes; - link.counterLinkWritten = false; } } } diff --git a/brouter-expressions/src/main/java/btools/expressions/BExpressionContext.java b/brouter-expressions/src/main/java/btools/expressions/BExpressionContext.java index 72540b5..efca5bd 100644 --- a/brouter-expressions/src/main/java/btools/expressions/BExpressionContext.java +++ b/brouter-expressions/src/main/java/btools/expressions/BExpressionContext.java @@ -208,16 +208,22 @@ public final class BExpressionContext } } - public String getCsvDescription( byte[] ab ) + public String getCsvDescription( boolean inverseDirection, byte[] ab ) { - StringBuilder sb = new StringBuilder( 200 ); - decode( lookupData, ab ); - for( int inum = 0; inum < lookupValues.size(); inum++ ) // loop over lookup names - { - BExpressionLookupValue[] va = lookupValues.get(inum); - sb.append( '\t' ).append( va[lookupData[inum]].toString() ); - } - return sb.toString(); + int inverseBitByteIndex = readVarLength ? 0 : 7; + int abLen = ab.length; + byte[] ab_copy = new byte[abLen]; + System.arraycopy( ab, 0, ab_copy, 0 , abLen ); + if ( inverseDirection ) ab_copy[inverseBitByteIndex] ^= 1; + + StringBuilder sb = new StringBuilder( 200 ); + decode( lookupData, ab_copy ); + for( int inum = 0; inum < lookupValues.size(); inum++ ) // loop over lookup names + { + BExpressionLookupValue[] va = lookupValues.get(inum); + sb.append( '\t' ).append( va[lookupData[inum]].toString() ); + } + return sb.toString(); } public String getCsvHeader() @@ -327,12 +333,15 @@ public final class BExpressionContext - public void evaluate( boolean inverseDirection, byte[] ab, BExpressionReceiver receiver ) + /** + * evaluates the data in the given byte array + * + * @return true if the data is equivilant to the last calls data + */ + public boolean evaluate( boolean inverseDirection, byte[] ab, BExpressionReceiver receiver ) { int inverseBitByteIndex = readVarLength ? 0 : 7; - - _receiver = receiver; - + int abLen = ab.length; boolean equalsCurrent = currentHashBucket >= 0 && abLen == currentByteArray.length; if ( equalsCurrent ) @@ -348,7 +357,7 @@ public final class BExpressionContext if ( equalsCurrent ) { - return; + return true; } else { @@ -371,11 +380,13 @@ public final class BExpressionContext if ( abBucket[i] != currentByteArray[i] ) { hashBucketEquals = false; break; } } } - if ( hashBucketEquals ) return; + if ( hashBucketEquals ) return false; _arrayBitmap[currentHashBucket] = currentByteArray; - decode( lookupData, ab ); + _receiver = receiver; + + decode( lookupData, currentByteArray ); evaluate( lookupData ); _arrayCostfactor[currentHashBucket] = variableData[costfactorIdx]; @@ -384,6 +395,7 @@ public final class BExpressionContext _arrayNodeAccessGranted[currentHashBucket] = variableData[nodeaccessgrantedIdx]; _receiver = null; + return false; } public void dumpStatistics() diff --git a/brouter-map-creator/src/main/java/btools/mapcreator/WayLinker.java b/brouter-map-creator/src/main/java/btools/mapcreator/WayLinker.java index c0abb39..983915b 100644 --- a/brouter-map-creator/src/main/java/btools/mapcreator/WayLinker.java +++ b/brouter-map-creator/src/main/java/btools/mapcreator/WayLinker.java @@ -83,7 +83,7 @@ public class WayLinker extends MapCreatorBase creationTimeStamp = System.currentTimeMillis(); - abUnifier = new ByteArrayUnifier( 16384 ); + abUnifier = new ByteArrayUnifier( 16384, false ); // then process all segments new WayIterator( this, true ).processDir( wayTilesIn, ".wt5" ); diff --git a/brouter-mapaccess/src/main/java/btools/mapaccess/OsmLinkReverse.java b/brouter-mapaccess/src/main/java/btools/mapaccess/OsmLinkReverse.java deleted file mode 100644 index 5b3fecf..0000000 --- a/brouter-mapaccess/src/main/java/btools/mapaccess/OsmLinkReverse.java +++ /dev/null @@ -1,11 +0,0 @@ -/** - * Dummy child of OsmLink just to encode the reverse-bit - * - * @author ab - */ -package btools.mapaccess; - - -public class OsmLinkReverse extends OsmLink -{ -} diff --git a/brouter-mapaccess/src/main/java/btools/mapaccess/OsmNode.java b/brouter-mapaccess/src/main/java/btools/mapaccess/OsmNode.java index 3f75d2f..af13cd7 100644 --- a/brouter-mapaccess/src/main/java/btools/mapaccess/OsmNode.java +++ b/brouter-mapaccess/src/main/java/btools/mapaccess/OsmNode.java @@ -240,12 +240,12 @@ public class OsmNode implements OsmPos // compute the reverse link if ( !link.counterLinkWritten ) { - OsmLink rlink = new OsmLinkReverse(); - + OsmLink rlink = new OsmLink(); + byte[] linkDescriptionBitmap = link.descriptionBitmap; rlink.ilonOrigin = tn.ilon; rlink.ilatOrigin = tn.ilat; rlink.targetNode = this; - rlink.descriptionBitmap = link.descriptionBitmap; // default for no transfer-nodes + rlink.descriptionBitmap = linkDescriptionBitmap; // default for no transfer-nodes OsmTransferNode previous = null; OsmTransferNode rtrans = null; for( OsmTransferNode trans = firstTransferNode; trans != null; trans = trans.next ) @@ -263,7 +263,7 @@ public class OsmNode implements OsmPos rtrans.ilat = trans.ilat; rtrans.selev = trans.selev; rtrans.next = previous; - rtrans.descriptionBitmap = trans.descriptionBitmap; + rtrans.descriptionBitmap = linkDescriptionBitmap; previous = rtrans; } rlink.encodeFirsttransfer(rtrans); @@ -332,17 +332,6 @@ public class OsmNode implements OsmPos } } - // mark the link to the given node as written, - // don't want to write the counter-direction - // in full details - public void markLinkWritten( OsmNode t ) - { - for( OsmLink link = firstlink; link != null; link = link.next ) - { - if ( link.targetNode == t) link.counterLinkWritten = true; - } - } - public OsmLink getReverseLink( int lon, int lat ) { for( OsmLink rlink = firstreverse; rlink != null; rlink = rlink.next ) diff --git a/brouter-mapaccess/src/main/java/btools/mapaccess/OsmNodesMap.java b/brouter-mapaccess/src/main/java/btools/mapaccess/OsmNodesMap.java index 3d9dfb3..5680bfc 100644 --- a/brouter-mapaccess/src/main/java/btools/mapaccess/OsmNodesMap.java +++ b/brouter-mapaccess/src/main/java/btools/mapaccess/OsmNodesMap.java @@ -13,7 +13,7 @@ public final class OsmNodesMap { private HashMap hmap = new HashMap(); - private ByteArrayUnifier abUnifier = new ByteArrayUnifier( 16384 ); + private ByteArrayUnifier abUnifier = new ByteArrayUnifier( 16384, false ); public ByteArrayUnifier getByteArrayUnifier() { diff --git a/brouter-util/src/main/java/btools/util/ByteArrayUnifier.java b/brouter-util/src/main/java/btools/util/ByteArrayUnifier.java index 24e09f8..5a9c692 100644 --- a/brouter-util/src/main/java/btools/util/ByteArrayUnifier.java +++ b/brouter-util/src/main/java/btools/util/ByteArrayUnifier.java @@ -3,12 +3,14 @@ package btools.util; public final class ByteArrayUnifier { private byte[][] byteArrayCache; + private int[] crcCrosscheck; private int size; - public ByteArrayUnifier( int size ) + public ByteArrayUnifier( int size, boolean validateImmutability ) { this.size = size; byteArrayCache = new byte[size][]; + if ( validateImmutability ) crcCrosscheck = new int[size]; } /** @@ -20,7 +22,7 @@ public final class ByteArrayUnifier */ public byte[] unify( byte[] ab ) { - int n = ab.length; + int n = ab.length; int crc = Crc32.crc( ab, 0, n ); int idx = (crc & 0xfffffff) % size; byte[] abc = byteArrayCache[idx]; @@ -34,6 +36,16 @@ public final class ByteArrayUnifier } if ( i == n ) return abc; } + if ( crcCrosscheck != null ) + { + if ( byteArrayCache[idx] != null ) + { + byte[] abold = byteArrayCache[idx]; + int crcold = Crc32.crc( abold, 0, abold.length ); + if ( crcold != crcCrosscheck[idx] ) throw new IllegalArgumentException( "ByteArrayUnifier: immutablity validation failed!" ); + } + crcCrosscheck[idx] = crc; + } byteArrayCache[idx] = ab; return ab; }