Astro::Nova::DMS - Perl representation of a libnova ln_dms (degrees, minutes, seconds)


Astro-Nova documentation Contained in the Astro-Nova distribution.

Index


Code Index:

NAME

Top

Astro::Nova::DMS - Perl representation of a libnova ln_dms (degrees, minutes, seconds)

SYNOPSIS

Top

  use Astro::Nova qw(functions ...);
  my $date = Astro::Nova::DMS->new();
  $date->set_year(...);
  # ...
  print $date->as_ascii(), "\n";
  my @members = $date->get_all();

  my $dms = Astro::Nova::DMS->from_string("4°50'2'' W"); # sgn=-1, degrees=4, minutes=50, seconds=2
  $dms = Astro::Nova::DMS->from_string("-4°50'"); # sgn=-1, degrees=4, minutes=50, seconds=0

DESCRIPTION

Top

This class represents a libnova ln_dms struct. The struct has the following layout:

  ln_dms {
    unsigned short  neg
    unsigned short  degrees
    unsigned short  minutes
    double          seconds
  }

METHODS

Top

new

Constructor returns a new Astro::Nova::DMS. Optionally takes key/value pairs for setting the struct members. Extra arguments are ignored. Uninitialized struct members are set to zero.

get_... / set_...

Get or set any of the class attributes. (See list above)

get_all

Returns all members as a list.

set_all

Sets all members. Takes a list of values which must be in the order shown above. Any missing values are ignored, undefs are skipped.

from_string

Parses a string of the form X°Y'Z'' DIR where X, Y, Z are numbers and DIR may be a direction [EWNS] (W sets sign to negative). Omitted parts are set to zero.

If called as a class methods, returns a new DMS. If called on an existing object, that object is modified.

as_ascii

Returns a human-readable ASCII table of the date information.

members

Returns a list of all members in order.

to_degrees / to_radians / to_hms

Convert to degrees or radians (returns a number).

to_hms Converts to Astro::Nova::HMS (hours).

from_degrees / from_radians / from_dms

When called as a class method, creates a new Astro::Nova::HMS object from the given degrees/radians value or Astro::Nova::DMS object.

When called as an object method, sets the current object's state instead.

SEE ALSO

Top

Astro::Nova

libnova website: http://libnova.sourceforge.net/

AUTHOR

Top

Steffen Mueller, <smueller@cpan.org>

COPYRIGHT AND LICENSE

Top


Astro-Nova documentation Contained in the Astro-Nova distribution.

package Astro::Nova::DMS;

use 5.008;
use strict;
use warnings;

use Astro::Nova;

# basic stuff is in Astro::Nova's XS!

sub members {
  return qw/neg degrees minutes seconds/
}

my $FLOAT = qr/(?:[+-]?)(?=\d|\.\d)\d*(?:\.\d*)?(?:[Ee]([+-]?\d+))?/;
sub from_string {
  my $class = shift;
  my $self = ref($class) ? $class : $class->new();
  my $string = shift;
  $string =~ m{
            ^\s*
            ([+-]?)\s*
            (?:(\d+)\s*°)?
            \s*
            (?:(\d+)\s*')?
            \s*
            (?:($FLOAT)\s*'')?
            \s*(?:([eEwWnNsS]))?\s*$
        }x or return();
  my ($sign, $deg, $min, $sec, $dir) = ($1, $2, $3, $4, $5);
  if (not grep {defined($_)} ($deg, $min, $sec)) {
    return();
  }
  $sign = 1 if not defined $sign;
  $sign = ($sign eq '-' ? -1 : 1);
  $sign *= -1 if $dir and $dir =~ /^[wW]$/;
  $self->set_neg($sign < 0 ? 1 : 0);
  $self->set_degrees(defined $deg ? $deg : 0);
  $self->set_minutes(defined $min ? $min : 0);
  $self->set_seconds(defined $sec ? $sec : 0);
  return $self;
}

sub as_ascii {
  my $self = shift;
  my $template = <<'HERE';
Negative:   %d
Degrees:    %d
Minutes:    %d
Seconds:    %f
HERE
  return sprintf($template, $self->get_all());
}

sub get_all {
  my $self = shift;
  return(map $self->$_(), map "get_$_", $self->members());
}

sub set_all {
  my $self = shift;
  foreach my $member (map "set_$_", $self->members) {
    last if not @_;
    my $value = shift @_;
    next if not defined $value;
    $self->$member($value);
  }
  return 1;
}

sub to_degrees {
  Astro::Nova::dms_to_deg(shift)
}

sub to_radians {
  Astro::Nova::dms_to_rad(shift)
}

sub to_hms {
  Astro::Nova::deg_to_hms(Astro::Nova::dms_to_deg(shift))
}

sub from_degrees {
  my $class = shift;
  my $obj = Astro::Nova::deg_to_dms(shift);
  return $obj if not ref $class;
  $class->set_all($obj->get_all());
  return $class;
}

sub from_radians {
  my $class = shift;
  my $obj = Astro::Nova::rad_to_dms(shift);
  return $obj if not ref $class;
  $class->set_all($obj->get_all());
  return $class;
}

sub from_hms {
  my $class = shift;
  my $obj = shift->to_dms();
  return $obj if not ref $class;
  $class->set_all($obj->get_all());
  return $class;
}


1;
__END__