Question

I am trying to figure out how to create a .ov2 file to add POI data to a TomTom GPS device. The format of the data needs to be as follow:

An OV2 file consists of POI records. Each record has the following data format.

  • 1 BYTE, char, POI status ('0' or '2')
  • 4 BYTES, long, denotes length of the POI record.
  • 4 BYTES, long, longitude * 100000
  • 4 BYTES, long, latitude * 100000
  • x BYTES, string, label for POI, x =3D=3D total length =96 (1 + 3 * 4)
  • Terminating null byte.

I found the following PHP code that is supposed to take a .csv file, go through it line by line, split each record and then write it into a new file in the proper format. I was hoping someone would be able to help me translate this to Java. I really only need the line I marked with the '--->' arrow. I do not know PHP at all, but everything other than that one line is basic enough that I can look at it and translate it, but I do not know what the PHP functions are doing on that one line. Even if someone could explain it well enough then maybe I could figure it out in Java. If you can translate it directly, please do, but even an explanation would be helpful. Thanks.

<?php 
$csv = file("File.csv"); 
$nbcsv = count($csv); 
$file = "POI.ov2"; 
$fp = fopen($file, "w"); 
for ($i = 0; $i < $nbcsv; $i++) { 
    $table = split(",", chop($csv[$i])); 
    $lon = $table[0]; 
    $lat = $table[1]; 
    $des = $table[2]; 
    --->$TT = chr(0x02).pack("V",strlen($des)+14).pack("V",round($lon*100000)).pack("V",round($lat*100000)).$des.chr(0x00); 
    @fwrite($fp, "$TT"); 
} 
fclose($fp);
?>
Was it helpful?

Solution

Load a file into an array, where each element is a line from the file.

$csv = file("File.csv"); 

Count the number of elements in the array.

$nbcsv = count($csv); 

Open output file for writing.

$file = "POI.ov2"; 
$fp = fopen($file, "w"); 

While $i < number of array items, $i++

for ($i = 0; $i < $nbcsv; $i++) { 

Right trim the line (remove all whitespace), and split the string by ','. $table is an array of values from the csv line.

    $table = split(",", chop($csv[$i])); 

Assign component parts of the table to their own variables by numeric index.

    $lon = $table[0]; 
    $lat = $table[1]; 
    $des = $table[2];

The tricky bit.

chr(02) is literally character code number 2. pack is a binary processing function. It takes a format and some data. V = unsigned long (always 32 bit, little endian byte order).

I'm sure you can work out the maths bits, but you need to convert them into little endian order 32 bit values.

. is a string concat operator.

Finally it is terminated with chr(0). Null char.

$TT = chr(0x02).
  pack("V",strlen($des)+14).
  pack("V",round($lon*100000)).
  pack("V",round($lat*100000)).
  $des.chr(0x00); 

Write it out and close the file.

    @fwrite($fp, "$TT"); 
} 
fclose($fp);

OTHER TIPS

The key in JAVA is to apply proper byte order ByteOrder.LITTLE_ENDIAN to the ByteBuffer.

The whole function:

private static boolean getWaypoints(ArrayList<Waypoint> geopoints, File f)
{
try{
FileOutputStream fs = new FileOutputStream(f);

for (int i=0;i<geopoints.size();i++)
{

     fs.write((byte)0x02);
     String desc = geopoints.get(i).getName();

     int poiLength = desc.toString().length()+14;
     fs.write(ByteBuffer.allocate(4).order(ByteOrder.LITTLE_ENDIAN).putInt(poiLength).array());

     int lon = (int)Math.round((geopoints.get(i).getLongitudeE6()/1E6)*100000);
     fs.write(ByteBuffer.allocate(4).order(ByteOrder.LITTLE_ENDIAN).putInt(lon).array());        

     int lat = (int)Math.round((geopoints.get(i).getLatitudeE6()/1E6)*100000);
     fs.write(ByteBuffer.allocate(4).order(ByteOrder.LITTLE_ENDIAN).putInt(lat).array());


     fs.write(desc.toString().getBytes());

     fs.write((byte)0x00);

}


    fs.close();

    return true;

}
catch (Exception e)
{
    return false;
}


}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top