Co jsem slyšel tak zapnutí POI zpomaluje TomToma všem. Při navigaci je to pak klidně jedno překreslení za 5s, u optimalizovaných souborů pak osobně v rychlosti mezi zapnutými a vypnutými POI nevidím rozdíl. PHP bohužel neumím, maximálně to můžu přepsat do Perlu ale ten algoritmus není nic složitého. Matice by sice šla taky, ale ten binární strom bylo první co mě napadlo, je to nejjednodušší. Záznam typu 1 je vždy jen "prefix" dalších záznamů, přidává před ně bounding box. Když TomTom pozná že bounding box je celý mimo, jeho zbytek přeskočí. Jsem to teda přepsal do Perlu, a rovnou to z půlení předělal na quadtree. Teď je to kompletní použitelnej program, zkus to na některý větší OV2 file, a uvidíš.
Kód: Vybrat vše
#! /usr/bin/perl
use strict;
sub encode {
my @list = @_;
if (scalar(@list) <= 4) {
my $ret;
foreach my $i (@list) {
my ($x, $y, $n) = @$i;
$ret .= pack "CVVV", 2, 14 + length($n), $x, $y;
$ret .= $n . "\0";
}
return $ret;
}
my ($xl, $yl) = @{$list[0]};
my ($xh, $yh) = ($xl + 1, $yl + 1);
foreach my $i (@list) {
my ($x, $y, $n) = @$i;
$xl = $x if $x < $xl;
$yl = $y if $y < $yl;
$xh = $x + 1 if $x + 1 > $xh;
$yh = $y + 1 if $y + 1 > $yh;
}
my @div = ([], [], [], []);
foreach my $i (@list) {
my ($x, $y, $n) = @$i;
my $idx = ($x >= ($xl + $xh)/2) * 2 +
($y >= ($yl + $yh)/2);
push @{$div[$idx]}, $i;
}
my $ret = join "", map { encode(@$_); } @div;
my $hdr = pack "CVVVVV", 1, 21 + length($ret), $xh, $yh, $xl, $yl;
return $hdr . $ret;
}
if (scalar(@ARGV) != 2) {
print STDERR <<EOF
OV2 file optimizer
use: $0 <infile> <outfile>
EOF
;
exit;
}
my @list;
open my $in, "<$ARGV[0]";
open my $out, ">$ARGV[1]";
while (read $in, $a, 5) {
my ($c, $n) = unpack "CV", $a;
if ($c != 2) {
read $in, $a, $c == 1 ? 16 : $n - 5;
next;
}
read $in, $a, 8;
my ($x, $y) = unpack "VV", $a;
read $in, $a, $n - 13;
push @list, [$x, $y, substr($a, 0, -1)];
}
print $out encode(@list);