#!/usr/bin/perl -w 
# Лицензия "Делайте что хотите", а если очень нужно, то GPL :) 
# Сообщения на английском, чтобы не связываться с локалями и gettext :( .
# Кроме стандартных расширений perl необходим модуль perl::Magick.
#
# Эта программа предназначена для прорисовки маршрута qpegps на карте
# Все координаты - в десятичных долях градусов

use POSIX;
use File::Basename;
use Image::Magick;
use encoding 'cp1251';

sub readkoordfile ($$$) {
my ($koordfname, $mapfname, $res) = @_;
my @tmp;
    open (IN, $koordfname) or die "Cannot open maps.txt!";    
    while(<IN>) {
	chomp;
	if (not m/^#/) {
	    if (m/$mapfname/) {
		@tmp = split(' ', $_); # В именах файлов карт не должно быть пробелов
		@{${$res}{$mapfname}} = ($tmp[5], $tmp[6], $tmp[7], $tmp[8], $tmp[9], $tmp[10], $tmp[11], $tmp[12]);
	    };
	};
    };
    close (IN);
};

sub readtrackfile ($$) {
my ($trackfname, $res) = @_;
my @tmp;
    open (IN, $trackfname) or die "Cannot open track \"$trackfname\"!";    
    while(<IN>) {
	chomp;
	if (not m/^#/) { 
	    @tmp = split(' ', $_); 
	    push (@{$res}, $tmp[0]." ".$tmp[1]); # Нужны только два первых поля с координатами точек 
	};
    };
    close (IN);
};


if ( not $#ARGV + 1) { 
    print "Track plotter v.0.1\n";
    print "\ngpsmapper FILENAME maps.txt TRACKFILE [color]\n";
    print "\nThis script will plot your track records in qpegps format on a raster image.\n";	
} else { 

my $suffixes = "\.[G|g][I|i][F|f]|\.[J|j][P|p][G|g]|\.[P|p][N|n][G|g]|\.[B|b][M|m][P|p]";
my $mapfname = $ARGV[0];
my $basemapname = fileparse($mapfname, $suffixes);
my $koordfname = $ARGV[1]; 
my $trackfname = $ARGV[2]; 
my $color; if (defined $ARGV[3]) {$color = $ARGV[3]} else {$color = 'red'};
my $skipfilter = 100; # 0 означает выключить фильтрацию, значение ниже 50-60 может привести к разрывам в линии (зависит от скорости и интервала записи точек)

my ($first_x, $first_y, $first_lon, $first_lat);
my ($secnd_x, $secnd_y, $secnd_lon, $secnd_lat);
my ($lonperpix, $latperpix, $baselon, $baselat); #шаг координат в 1 пикселе и координаты пикселя 0х0 
my %mapkoords; #ключи - имена карт, значения - массивы координат x1 y1 lon1 lat1 x2 y2 lon2 lat2
my @track; # массив для хранения координат точек
my ($map_x, $map_y, $x_corr, $y_corr); # Размеры карты и поправки для вычисления положения точек на карте


    readtrackfile($trackfname, \@track); 
    readkoordfile($koordfname, $mapfname, \%mapkoords); #FIXME Нужно уметь работать с несколькими картами т.к. путь переходит с одного листа на другой
    
    foreach $mapfname (keys(%mapkoords)){ # Обработка всех карт по списку

	# Подготовка
	$first_lon = $mapkoords{$mapfname}[0];
	$first_lat = $mapkoords{$mapfname}[1];
	$first_x = $mapkoords{$mapfname}[2];
	$first_y = $mapkoords{$mapfname}[3];
	$secnd_lon = $mapkoords{$mapfname}[4];
	$secnd_lat = $mapkoords{$mapfname}[5];
	$secnd_x = $mapkoords{$mapfname}[6];
	$secnd_y = $mapkoords{$mapfname}[7];

	$lonperpix = ($secnd_lon - $first_lon)/($secnd_x - $first_x); # Шаг координат в 1 пикселе, две точки должны быть расположены диагонально, в углах картинки
	$latperpix = ($secnd_lat - $first_lat)/($secnd_y - $first_y); 

	$baselon = $first_lon - ($first_x * $lonperpix); # Поправка, если координаты точки1 не 0х0 
	$baselat = $first_lat - ($first_y * $latperpix);
	
	$x_corr = floor($baselon/$lonperpix);
	$y_corr = floor($baselat/$latperpix);
	
	# Чтение картинки
        print "Plotting map \"$mapfname\"...\n";
	$map=Image::Magick->new(); 
        $x=$map->ReadImage($mapfname);
	warn "$x" if "$x";
	($map_x, $map_y)=$map->Get('width', 'height'); # Получение свойств картинки

	# Перебор точек маршрута
	foreach (@track) {
	    ($lat, $lon) = split(' ', $_);

	    $x_prev = $x; # Запомнить предыдущую точку
	    $y_prev = $y;
	    
	    $x = (floor($lon/$lonperpix) - $x_corr); # Вычислить пиксельные координаты новой точки
	    $y = (floor($lat/$latperpix) - $y_corr);
	    
	    if ($x >= 0 and $x <= $map_x and $y >=0 and $y <=$map_y) { # Фильтр точек, которые попадают на карту
		if (defined $x_prev and defined $y_prev) {
		    if ( not $skipfilter or abs($x_prev - $x) < $skipfilter and abs($y_prev - $y) < $skipfilter) { # Фильтр далеких "скачков"
			$map->Draw('stroke'=>$color, 'primitive'=>'line','points'=>"$x_prev,$y_prev $x,$y"); # Рисуем путь
		    };
		};
	    };	
	};
#	$map->Write("$basemapname-$trackfname.png");
	$map->Write("$mapfname");
	
    }
};