| Revision 10 (by dpavlin, 2007/10/16 09:27:16) |
added --flip-vertical option to stich.pl |
#!/usr/bin/perl -w
# stich.pl
#
# 10/15/07 22:02:18 CEST Dobrica Pavlinusic <dpavlin@rot13.org>
use strict;
use File::Find;
use Data::Dump qw/dump/;
use Imager;
use Getopt::Long;
# Mireo 1, Google 0
my $flip_vertical = 0;
GetOptions(
'flip-vertical' => \$flip_vertical,
);
my $path = shift @ARGV || die "usage: $0 path_to_dump_dir\n";
my ( $range, $usage );
my @files;
my $file_pos;
find( sub {
return unless -f $_;
if ( $_ =~ m/(\d+)-(\d+)/ ) {
push @files, $_;
my ( $x, $y ) = ( $1, $2 );
$range->{min}->{x} = $x if not defined $range->{min}->{x} or $x < $range->{min}->{x};
$range->{max}->{x} = $x if not defined $range->{max}->{x} or $x > $range->{max}->{x};
$range->{min}->{y} = $y if not defined $range->{min}->{y} or $y < $range->{min}->{y};
$range->{max}->{y} = $y if not defined $range->{max}->{y} or $y > $range->{max}->{y};
$usage->{x}->{$x}++;
$usage->{y}->{$y}++;
$file_pos->{$_} = { x => $x, y => $y };
warn "## $_\n";
} else {
warn "SKIPPED: $_\n";
}
}, $path );
print "range = ",dump( $range ), "\n";
print "usage = ",dump( $usage ). "\n";
my $step_size;
foreach my $axis ( 'x', 'y' ) {
my $last = $range->{min}->{$axis};
foreach my $v ( sort keys %{$usage->{$axis}} ) {
next if $v == $last;
$step_size->{$axis}->{ $v - $last }++;
$last = $v;
}
undef $last;
}
print "step_size = ",dump( $step_size ),"\n";
my $step = {
x => ( sort { $step_size->{x}->{$b} <=> $step_size->{x}->{$a} } keys %{ $step_size->{x} } )[0],
y => ( sort { $step_size->{y}->{$b} <=> $step_size->{y}->{$a} } keys %{ $step_size->{y} } )[0],
};
print "selected step = ",dump( $step ),"\n";
my $img = Imager->new();
$img->read( file => $path . '/' . $files[0] ) or die $img->errstr();
my $tile_size = {
x => $img->getwidth,
y => $img->getheight,
};
print "tile_size = ",dump( $tile_size ),"\n";
my $x_tiles = ( $range->{max}->{x} - $range->{min}->{x} ) / $step->{x};
my $y_tiles = ( $range->{max}->{y} - $range->{min}->{y} ) / $step->{y};
my $x_size = $x_tiles * $tile_size->{x};
my $y_size = $y_tiles * $tile_size->{y};
print "final map size: $x_size x $y_size from $x_tiles x $y_tiles tiles\n";
my $map = Imager->new( xsize => $x_size, ysize => $y_size ) or $img->errstr();
foreach my $tile_file ( @files ) {
$img->read( file => "$path/$tile_file" ) or die $img->errstr();
# this is specific to globe position, I guess ... this is europe
my $x = ( $file_pos->{$tile_file}->{x} - $range->{min}->{x} ) / $step->{x};
my $y;
if ( $flip_vertical ) {
$y = ( $range->{max}->{y} - $file_pos->{$tile_file}->{y} ) / $step->{y};
} else {
$y = ( $file_pos->{$tile_file}->{y} - $range->{min}->{y} ) / $step->{y};
}
printf("%3dx%-3d %s\n", $x, $y, $tile_file);
$map->paste(
src => $img,
left => $x * $tile_size->{x},
top => $y * $tile_size->{y},
);
}
$path =~ s/\W+/_/g;
$path =~ s/^_+//;
$path =~ s/_+$//;
$map->write( file => "$path.png" ) or die $img->errstr();