/** * Container for link between two Osm nodes * * @author ab */ package btools.mapaccess; import btools.util.ByteDataReader; public final class GeometryDecoder { private ByteDataReader r = new ByteDataReader( null ); private OsmTransferNode[] cachedNodes; private int nCachedNodes = 128; public GeometryDecoder() { // create some caches cachedNodes = new OsmTransferNode[nCachedNodes]; for( int i=0; i<nCachedNodes; i++ ) { cachedNodes[i] = new OsmTransferNode(); } } public OsmTransferNode decodeGeometry( byte[] geometry, OsmNode sourceNode, OsmNode targetNode, boolean reverseLink ) { OsmTransferNode firstTransferNode = null; OsmTransferNode lastTransferNode = null; OsmNode startnode = reverseLink ? targetNode : sourceNode; r.reset( geometry ); int olon = startnode.ilon; int olat = startnode.ilat; int oselev = startnode.selev; int idx = 0; while ( r.hasMoreData() ) { OsmTransferNode trans = idx < nCachedNodes ? cachedNodes[idx++] : new OsmTransferNode(); trans.ilon = olon + r.readVarLengthSigned(); trans.ilat = olat + r.readVarLengthSigned(); trans.selev = (short)(oselev + r.readVarLengthSigned()); olon = trans.ilon; olat = trans.ilat; oselev = trans.selev; if ( reverseLink ) // reverse chaining { trans.next = firstTransferNode; firstTransferNode = trans; } else { trans.next = null; if ( lastTransferNode == null ) { firstTransferNode = trans; } else { lastTransferNode.next = trans; } lastTransferNode = trans; } } return firstTransferNode; } }