package btools.mapaccess; import btools.codec.DataBuffers; import btools.codec.NoisyDiffCoder; import btools.codec.StatCoderContext; import btools.codec.TagValueCoder; import btools.codec.TagValueValidator; import btools.codec.TagValueWrapper; import btools.codec.WaypointMatcher; import btools.util.ByteDataWriter; import btools.util.IByteArrayUnifier; /** * DirectWeaver does the same decoding as MicroCache2, but decodes directly * into the instance-graph, not into the intermediate nodes-cache */ public final class DirectWeaver extends ByteDataWriter { private long id64Base; private int size = 0; public DirectWeaver( StatCoderContext bc, DataBuffers dataBuffers, int lonIdx, int latIdx, int divisor, TagValueValidator wayValidator, WaypointMatcher waypointMatcher, OsmNodesMap hollowNodes ) { super( null ); int cellsize = 1000000 / divisor; id64Base = ((long)(lonIdx*cellsize))<<32 | (latIdx*cellsize); TagValueCoder wayTagCoder = new TagValueCoder( bc, dataBuffers, wayValidator ); TagValueCoder nodeTagCoder = new TagValueCoder( bc, dataBuffers, null ); NoisyDiffCoder nodeIdxDiff = new NoisyDiffCoder( bc ); NoisyDiffCoder nodeEleDiff = new NoisyDiffCoder( bc ); NoisyDiffCoder extLonDiff = new NoisyDiffCoder(bc); NoisyDiffCoder extLatDiff = new NoisyDiffCoder(bc); NoisyDiffCoder transEleDiff = new NoisyDiffCoder( bc ); size = bc.decodeNoisyNumber( 5 ); int[] faid = size > dataBuffers.ibuf2.length ? new int[size] : dataBuffers.ibuf2; bc.decodeSortedArray( faid, 0, size, 29, 0 ); OsmNode[] nodes = new OsmNode[size]; for( int n = 0; n> 32 ); int ilat = (int) ( id & 0xffffffff ); OsmNode node = hollowNodes.get( ilon, ilat ); if ( node == null ) { node = new OsmNode( ilon, ilat ); } else { node.visitID = 1; hollowNodes.remove( node ); } nodes[n] = node; } int netdatasize = bc.decodeNoisyNumber( 10 ); // (not needed for direct weaving) ab = dataBuffers.bbuf1; aboffset = 0; int selev = 0; for( int n=0; n 0 ) { geometry = new byte[aboffset]; System.arraycopy( ab, 0, geometry, 0, aboffset ); } if ( nodeIdx != n ) // valid internal (forward-) link { OsmNode node2 = nodes[nodeIdx]; OsmLink link = node.isLinkUnused() ? node : ( node2.isLinkUnused() ? node2 : null ); if ( link == null ) { link = new OsmLink(); } link.descriptionBitmap = wayTags.data; link.geometry = geometry; node.addLink( link, isReverse, node2 ); } else // weave external link { node.addLink( linklon, linklat, wayTags.data, geometry, hollowNodes, isReverse ); node.visitID = 1; } } } // ... loop over links } // ... loop over nodes hollowNodes.cleanupAndCount( nodes ); } private static final long[] id32_00 = new long[1024]; private static final long[] id32_10 = new long[1024]; private static final long[] id32_20 = new long[1024]; static { for( int i=0; i<1024; i++ ) { id32_00[i] = _expandId( i ); id32_10[i] = _expandId( i << 10 ); id32_20[i] = _expandId( i << 20 ); } } private static long _expandId( int id32 ) { int dlon = 0; int dlat = 0; for( int bm = 1; bm < 0x8000; bm <<= 1 ) { if ( (id32 & 1) != 0 ) dlon |= bm; if ( (id32 & 2) != 0 ) dlat |= bm; id32 >>= 2; } return ((long)dlon)<<32 | dlat; } public long expandId( int id32 ) { return id64Base + id32_00[ id32 & 1023 ] + id32_10[ (id32>>10) & 1023 ] + id32_20[ (id32>>20) & 1023 ]; } }