Generating OV2 Files

I

IsRaEl

Hello,

I've neve done BinaryWriting, but i need to generate TomTom and
Destinator files from a POI database.

I manage to get this specification over the internet, but i'm having
troubles to generate the file

// 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 == total length – (1 + 3 * 4)
including terminating 0.

Here is the code i'm trying to make it work.

FileStream fs = File.Create("C:\\test.dat");
BinaryWriter bw = new BinaryWriter(fs);

char ini= (char)0x02;
long a = "40 km/h".Length + 20;
long b = (long)(-46.75068 * 100000);
long c = (long)(-23.50811 * 100000);
string d = "40 km/h";
char end = (char)0x00;


bw.Write(ini);
bw.Write(a);
bw.Write(b);
bw.Write(c);
bw.Write(d);
bw.Write(end);

bw.Close();
fs.Close();

Is there anyway to get a diferent result, since i'm a newbie in binary
files??

Thanks in advance..
 
I

IsRaEl

Just for reference, i found this php code that seems to do the job,

$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])); // Every ligne in this type:
longitude,latitude,description
$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);
 
J

Jason Newell

Peter,

The first thing that came to my mind on this post was binary
serialization. I've done a lot of XML serialization but not binary
serialization. Would binary serialization give him enough granular
control to easily create the file. I would look into it myself but I
don't have time at the moment.

Jason Newell
www.jasonnewell.net

Peter said:
Hello,

I've neve done BinaryWriting, but i need to generate TomTom and
Destinator files from a POI database.

I manage to get this specification over the internet, but i'm having
troubles to generate the file

// 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 == total length – (1 + 3 * 4)
including terminating 0.

There are at least two issues here:

-- character encoding
-- byte order

Your description of the "label for POI" isn't very clear either, but it
looks like you are saying that the length of the label (including the
terminating null) is "x", where that's identical to the "total length"
of the record minus the size of the other fields. I'm making the
assumption that's the case.
Here is the code i'm trying to make it work.

FileStream fs = File.Create("C:\\test.dat");
BinaryWriter bw = new BinaryWriter(fs);

char ini= (char)0x02;

In C#/.NET, a "char" is two bytes, not one.
long a = "40 km/h".Length + 20;

Not sure where you get "+ 20" here.
long b = (long)(-46.75068 * 100000);
long c = (long)(-23.50811 * 100000);

In C#, a "long" is eight bytes, not four.
string d = "40 km/h";

In C#, a "string" is UTF-16. The default encoding used for a
BinaryWriter is UTF-8.
char end = (char)0x00;

See above.

Basically, you need to start by identifying the character encoding used
in your file. It's probably ASCII, but you need to know _for sure_.
You also need to identify the byte order of the file. If you're lucky,
it's little-endian, which is the byte order used in .NET and you can
just write the data out directly. If it's big-endian, you'll have to
swap bytes before writing them.

Assuming ASCII and little-endian, something like this might work:

string strLabel = "40 km/h";

// The whole record is one byte, plus 3 * 4 bytes, plus a final byte,
// plus the number of characters in the string.
int cbRecord = strLabel.Length + 14;
int lon = (int)(-46.75068 * 100000);
int lat = (int)(-23.50811 * 100000);
byte[] rgbLabel = Encoding.ASCII.GetBytes(strLabel + '\0');

bw.Write((byte)0x02);
bw.Write(cbRecord);
bw.Write(lon);
bw.Write(lat);
bw.Write(rgbLabel);

An alternative would be to create the BinaryWriter by specifying the
encoding:

BinaryWriter bw = new BinaryWriter(fs, Encoding.ASCII);

Then you don't need to explicitly convert to bytes for the last
statement, which would instead look like:

bw.Write(strLabel + '\0');

Ironically, the character encoding was probably _not_ what was causing
the incorrect output, since the default encoding of UTF-8 is identical
to ASCII for the 128 character values in ASCII. The real problem was in
writing "long" values instead of "int" values. :) But, you really
should be explicit about the encoding, to guarantee correct behavior (of
course, if the encoding for the file format is UTF-8, then you can use
the default, but IMHO it's still better to be explicit).

Pete
 
I

IsRaEl

That depends on how he uses it.  If he writes his own formatter, he can 
make binary serialization do whatever he wants.  But the default  
formatters don't provide that kind of control (in fact, the two I'm  
familiar with really bloat the data).

He may well be best off using BinaryWriter directly.  He just has to use  
it correctly.  :)

Pete

Hey Pete...thanks for the tips..

By POI i mean Point Of Interest, it's GPS data...

I found out that the encoding is the UTF-8 and seems to be little-
endian...

Thanks for all the help...i will try this code you send, and then i
will give a reply.

Thanks again...
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top