# -*- perl -*- # # $Id: Globe.pm,v 1.10 2005/04/05 22:36:10 eserte Exp $ # Author: Slaven Rezic # # Copyright (C) 2000 Slaven Rezic. All rights reserved. # This package is free software; you can redistribute it and/or # modify it under the same terms as Perl itself. # # Mail: eserte@cs.tu-berlin.de # WWW: http://user.cs.tu-berlin.de/~eserte/ # # see also ..../bbbike/misc/globe/show.pl package GIS::Globe; use strict; use vars qw($VERSION); $VERSION = "0.02"; sub new { my($class, %args) = @_; my $self = {}; bless $self, $class; if ($args{-file}) { my $file = $args{-file}; $self->{HeaderFile} = "$file.hdr"; $self->{FormatFile} = "$file.fmt"; $self->{BinaryFile} = "$file.bin"; } $self; } # REPO BEGIN # REPO NAME pi /home/e/eserte/src/repository # REPO MD5 bb2103b1f2f6d4c047c4f6f5b3fa77cd sub _pi () { 4 * atan2(1, 1) } # 3.141592653 # REPO END sub read_files { my $self = shift; $self->read_header_file; $self->read_format_file; $self->read_binary_file; } sub read_header_file { my $self = shift; open(F, $self->{HeaderFile}) or die "Can't open $self->{HeaderFile}: $!"; $self->{Header} = {}; while() { chomp; my($k,$v) = split(/\s*=\s*/, $_, 2); # use old values... if ($k eq 'elev_m_min') { $k = 'elev_m_minimum' } if ($k eq 'elev_m_max') { $k = 'elev_m_maximum' } $self->{Header}{$k} = $v; } close F; } sub read_format_file { # NYI assume little endian } sub read_binary_file { my $self = shift; my $data = []; my $num_rows = $self->{Header}{number_of_rows}; my $num_cols = $self->{Header}{number_of_columns}; my $undef_val = $self->{Header}{elev_m_missing_flag}; open(F, $self->{BinaryFile}) or die "Can't open $self->{BinaryFile}: $!"; for my $y (0 .. $num_rows-1) { read F, my($buf), $num_cols*2; my $row = []; for my $x (0 .. $num_cols-1) { my $h = unpack("s", substr($buf, $x*2, 2)); if ($h == $undef_val) { $h = undef; } push @$row, $h; } push @$data, $row; } close F; $self->{Data} = $data; } sub width { $_[0]->{Header}{number_of_columns} } sub height { $_[0]->{Header}{number_of_rows} } sub gridsize { $_[0]->{Header}{grid_size} } sub polar_to_index { my($self, $polar_x, $polar_y) = @_; my $grid = $self->{Header}{grid_size}; my $inx_x = ($polar_x+$grid-$self->{Header}{left_map_x}) / $grid; my $inx_y = $self->{Header}{number_of_rows} - ($polar_y+$grid/2-$self->{Header}{lower_map_y}) / $grid; ($inx_x, $inx_y); } sub index_to_polar { my($self, $inx_x, $inx_y) = @_; my $grid = $self->{Header}{grid_size}; my $polar_x = $inx_x*$grid + $self->{Header}{left_map_x} + $grid; my $polar_y = ($self->{Header}{number_of_rows}-$inx_y)*$grid + $self->{Header}{lower_map_y} - $grid/2; ($polar_x, $polar_y); } =head2 get_data_by_polar($polar_x,$polar_y) Return height, index x and index y for polar coordinates x/y. =cut sub get_data_by_polar { my($self, $polar_x, $polar_y) = @_; my($inx_x, $inx_y) = $self->polar_to_index($polar_x, $polar_y); ($self->{Data}[ $inx_y ][ $inx_x ], $inx_x, $inx_y); } =head2 get_data_by_index($x,$y) Return height, polar x and polar y for data column $x and data row $y. =cut sub get_data_by_index { my($self, $inx_x, $inx_y) = @_; my $h = $self->{Data}[ $inx_y ][ $inx_x ]; my($polar_x, $polar_y) = $self->index_to_polar($inx_x, $inx_y); ($h, $polar_x, $polar_y); } sub show_suggested_aspect { my $self = shift; my $w = $self->{Header}{'number_of_columns'}; my $h = $self->{Header}{'number_of_rows'}; my $long_w = $self->{Header}{'right_map_x'} - $self->{Header}{'left_map_x'}; my $lat_h = $self->{Header}{'upper_map_y'} - $self->{Header}{'lower_map_y'}; my $center_lat = $self->{Header}{'lower_map_y'} + $lat_h/2; my $aspect = cos($center_lat/180*_pi); my $aspect_1 = 1/$aspect; my $change_h = int($h/$aspect); my $change_w = int($w/$aspect_1); print STDERR < "$FindBin::RealBin/../misc/globe/berlin"; $gis->read_files; print STDERR "Hafas coords x,y > "; while() { s/^\s+//; # trim leading space my($hafas_x,$hafas_y) = split /,/; my($polar_x,$polar_y) = $std->map2map($polar, $hafas_x, $hafas_y); print STDERR "$polar_x,$polar_y => " . ($gis->get_data_by_polar($polar_x,$polar_y))[0] . "m\n"; print STDERR "> "; } __END__