# untested use Math::Trig; my $Radius = 6378569.135 # in metres, so need $scale also in metres sub ReCentre { my ( $lat, $long, $direction, $scale ) = @_; # scale should be passed as the change in degrees # of latitude afforded by a 100 pixel move # - this routine then handles the effects of # non-linear longitude automatically $lat %= 180; # transform from signed to unsigned ring element # handle lateral move if ( $direction eq 'W' ) { $direction = 'E'; $scale = -$scale; } if ( $direction eq 'E' ) { return ( Ensign( $lat + 100 * $scale), $long ); # i.e. move while in unsigned transformation # before converting back to signed } # handle logitudinal move $long = tan( $long*pi()/180.0 ) * $Radius; # Project Mercatorially $scale = -$scale if ( $direction eq 'S' ); return ( $lat, 180.0 * atan( $long + 100*$scale )/pi() ); # i.e. move scaled distance while on Mercator projection, # and then reverse projection to get degrees. } sub Ensign { # convert back from unsigned ring element to degrees of latitude ( $_[0] > 90 ) ? $_[0] - 180 : $_[0]; }