I once wrote a java program to calculate track length with the pth files.
output for KY1 is
Number of Nodes: 250
FinishLine: 30
Track length: 2980m
import java.io.*;
import java.nio.ByteBuffer;
public class LFSTrackLength {
/*
1) X,Y,Z int : 32-bit fixed point world coordinates (1 metre = 65536)
X and Y are ground coordinates, Z is up.
2) float : 32 bit floating point number
FILE DESCRIPTION :
==================
num unit offset description
--- ---- ------ -----------
HEADER BLOCK :
6 char 0 LFSPTH : do not read file if no match
1 byte 6 version : 0 - do not read file if > 0
1 byte 7 revision : 0 - do not read file if > 0
1 int 8 num nodes : number
1 int 12 finish line : number
......NODE BLOCKS
NODE BLOCK :
1 int 0 centre X : fp
1 int 4 centre Y : fp
1 int 8 centre Z : fp
1 float 12 dir X : float
1 float 16 dir Y : float
1 float 20 dir Z : float
1 float 24 limit left : outer limit
1 float 28 limit right : outer limit
1 float 32 drive left : road limit
1 float 36 drive right : road limit
*/
/**
* @param args
*/
public static void main(String[] args) {
FileInputStream pth = null;
final int NodeLength = 40;
double length = 0;
byte[] buf = new byte[4000];
if(args.length < 1) {
System.out.println("Usage: java LFSTrackLength trackfile.pth");
System.exit(1);
}
try {
pth = new FileInputStream(args[0]);
} catch (IOException ioE) {
System.out.println( ioE );
System.exit(1);
}
if(pth == null) {
System.out.println( "Error gettin access to the file !");
System.exit(1);
}
// read header
try {
pth.read(buf,0,16);
} catch( IOException ioE ) {
System.out.println( ioE );
try {
pth.close();
} catch (IOException ioE2) {}
System.exit(1);
}
// check file description
if(!new String(buf,0,6).equals("LFSPTH") ||
buf[6] != 0 || buf[7] !=0) {
System.out.println("Wrong file type !");
try {
pth.close();
} catch (IOException ioE2) {}
System.exit(1);
}
ByteBuffer wrapper = ByteBuffer.wrap(buf);
wrapper.order(java.nio.ByteOrder.LITTLE_ENDIAN);
int NumNodes = wrapper.getInt(8);
System.out.println("Number of Nodes: " + NumNodes);
System.out.println("FinishLine: " + wrapper.getInt(12));
int NodesLeft = NumNodes;
int NodesRead = 0;
int[] StartPoint = null;
int[] LastPoint = null;
while(NodesLeft > 0) {
int NodesToRead = 0;
if(NodesLeft > 100) // read full buffer
NodesToRead = 100;
else
NodesToRead = NodesLeft;
try {
int BytesRead = pth.read(buf,0,NodesToRead * NodeLength);
NodesRead = BytesRead/40;
} catch( IOException ioE ) {
System.out.println( ioE );
try {
pth.close();
} catch (IOException ioE2) {}
System.exit(1);
}
for(int i = 0; i < NodesRead; i++) {
int offset = i * NodeLength;
int x = wrapper.getInt(offset);
int y = wrapper.getInt(offset + 4);
int z = wrapper.getInt(offset + 8);
// first point on path
if(StartPoint == null) {
StartPoint = new int[3];
StartPoint[0] = x;
StartPoint[1] = y;
StartPoint[2] = z;
LastPoint = new int[3];
} else { // measure distance between points
length += Math.sqrt(Math.pow(LastPoint[0] - x,2) + Math.pow(LastPoint[1] - y,2) + Math.pow(LastPoint[2] -z,2));
}
LastPoint[0] = x;
LastPoint[1] = y;
LastPoint[2] = z;
}
NodesLeft -= NodesRead;
}
length += Math.sqrt(Math.pow(LastPoint[0] - StartPoint[0],2) + Math.pow(LastPoint[1] - StartPoint[1],2) + Math.pow(LastPoint[2] - StartPoint[2],2));
System.out.println("Track length: " + Math.round(length/(double)65535) + "m");
}
}