#!/usr/bin/perl use strict; sub create_map($$) { my($width, $height) = @_; my($data) = []; print "Creating map..."; for(my $r=0; $r < $height; $r++) { $data->[$r] = []; } print "\n"; { width => $width, height => $height, data => $data } } sub merge_hgt($$$$$$) { my($map, $filename, $x, $y, $width, $height) = @_; my($mapdata) = $map->{'data'}; print "Merging $filename..."; if(open(HGT, "unzip -p $filename.zip $filename|")) { my($length) = $width * 2; # size of signed short my($r2) = $y; for(my $r=0; $r < $height; $r++) { my($buffer); my($offset) = 0; while ($offset < $length) { my($nread) = sysread HGT, $buffer, $length - $offset, $offset; if(defined $nread) { $offset += $nread; } else { print "(problem reading data: $!)"; } } my(@row) = unpack("n$width", $buffer); my($c2) = $x; for(my $c=0; $c < $width; $c++) { $row[$c] = -1 - ($row[$c] ^ 0xffff) if $row[$c] & 0x8000; $mapdata->[$r2]->[$c2] = $row[$c]; $c2++; } $r2++; } close HGT; print "\n"; } else { print STDERR "Couldn't open $filename\n"; } } sub save_map($$$$$$$) { my($map, $filename, $base, $x, $y, $width, $height) = @_; $width = $map->{'width'} unless defined $width; $height = $map->{'height'} unless defined $height; print "Saving map to $filename..."; open(TGA, ">$filename") or die "Error opening $filename for write: $!"; my($tgaheader)="\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00" . pack('v2', $width, $height) . "\x18\x20"; print TGA $tgaheader; foreach my $r (@{$map->{'data'}}[$y..$y+$map->{'height'}-1]) { foreach my $c (@{$r}[$x..$x+$map->{'width'}-1]) { my($v) = $c < -32700 ? 0 : $c - $base; print STDERR "\$base too high for $filename, should be less than $c\n" if $v < 0; print TGA pack('Cv', 0, $v); } } close TGA; print "\n"; } my($map) = create_map(2401, 2401); merge_hgt($map, 'N44W002.hgt', 0, 1200, 1201, 1201); merge_hgt($map, 'N45W002.hgt', 0, 0, 1201, 1201); merge_hgt($map, 'N44W001.hgt', 1200, 1200, 1201, 1201); merge_hgt($map, 'N45W001.hgt', 1200, 0, 1201, 1201); save_map($map, 'bordeaux.tga', -70, 0, 0, undef, undef);