brouter/brouter-mapaccess/src/main/java/btools/mapaccess/GeometryDecoder.java
Arndt Brenschede c517ccc2df version 1.4.9
2017-09-24 17:11:04 +02:00

81 lines
2.1 KiB
Java

/**
* 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;
// result-cache
private OsmTransferNode firstTransferNode;
private boolean lastReverse;
private byte[] lastGeometry;
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 )
{
if ( ( lastGeometry == geometry ) && ( lastReverse == reverseLink ) )
{
return firstTransferNode;
}
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;
}
}
lastReverse = reverseLink;
lastGeometry = geometry;
return firstTransferNode;
}
}