Astro-Montenbruck
view release on metacpan or search on metacpan
lib/Astro/Montenbruck/RiseSet.pm view on Meta::CPAN
my ( $evt, $jd ) = @_;
$res{$evt} = $jd;
$on_event->(@_);
},
on_noevent => sub {
$on_noevent->(@_);
},
%arg,
get_position => sub { _get_equatorial( $SU, $_[0] ) },
sin_h0 => sin( deg2rad( $H0_TWL{$type} ) ),
);
return %res;
}
riseset_func(%arg)->(
%arg,
get_position => sub { _get_equatorial( $SU, $_[0] ) },
sin_h0 => sin( deg2rad( $H0_TWL{$type} ) ),
on_event => $on_event,
on_noevent => $on_noevent
);
}
sub riseset {
my %arg = @_;
my $pla = delete $arg{planet};
my $h0 = do {
given ($pla) {
$H0_SUN when $SU;
$H0_MOO when $MO;
default { $H0_PLA }
}
};
my $func = riseset_func(%arg);
sub {
my %arg = ( on_event => sub { }, on_noevent => sub { }, @_ );
if (wantarray) {
# if caller asks for a result, collect events to %res hash
my %res;
$func->(
get_position => sub { _get_equatorial( $pla, $_[0] ) },
sin_h0 => sin( deg2rad($h0) ),
on_event => sub {
my ( $evt, $jd ) = @_;
$arg{on_event}->(@_);
$res{$evt} = { ok => 1, jd => $jd };
},
on_noevent => sub {
my ($state) = shift;
$arg{on_noevent}->(@_);
my $evt =
$state eq $STATE_NEVER_RISES ? $EVT_RISE : $EVT_SET;
$res{$evt} = { ok => 0, state => $state };
}
);
return %res;
}
# if caller doesn't ask for a result, just call the function with the callbacks
$func->(
get_position => sub { _get_equatorial( $pla, $_[0] ) },
sin_h0 => sin( deg2rad($h0) ),
on_event => $arg{on_event},
on_noevent => $arg{on_noevent},
);
}
}
sub rst {
# build top-level function for any event and any celestial object
# for given time and place
my $rst = rst_func(@_);
sub {
my $obj = shift;
my %arg = ( on_event => sub { }, on_noevent => sub { }, @_ );
my $h0 = do {
given ($obj) {
$H0_SUN when $SU;
$H0_MOO when $MO;
default { $H0_PLA }
}
};
# build second level functon for calculating any event for given object
my $evt_func = $rst->(
get_position => sub { _get_equatorial( $obj, $_[0] ) },
sin_h0 => sin( deg2rad($h0) )
);
if (wantarray) {
# if caller asks for a result, collect events to %res hash
my %res;
for (@RS_EVENTS) {
my ( $state, $jd ) = $evt_func->($_);
if ( $state eq $_ ) {
$arg{on_event}->( $_, $jd );
$res{$_} = { ok => 1, jd => $jd };
}
else {
$arg{on_noevent}->( $_, $state );
$res{$_} = { ok => 0, state => $state };
}
}
return %res;
}
# if caller doesn't ask for a result, just call the function with the callbacks
for (@RS_EVENTS) {
my ( $state, $jd ) = $evt_func->($_);
if ( $state eq $_ ) {
$arg{on_event}->( $_, $jd );
}
else {
$arg{on_noevent}->( $_, $state );
}
}
}
}
1;
__END__
=pod
=encoding UTF-8
=head1 NAME
Astro::Montenbruck::RiseSet - rise, set, transit.
=head1 SYNOPSIS
use Astro::Montenbruck::Ephemeris::Planet qw/:ids/;
use Astro::Montenbruck::MathUtils qw/frac/;
use Astro::Montenbruck::RiseSet::Constants qw/:all/;
use Astro::Montenbruck::RiseSet qw/:all/;
# create function for calculating rise/set/transit events for Munich, Germany, on March 23, 1989.
my $func = rst(
date => [1989, 3, 23],
phi => 48.1,
lambda => -11.6
);
# calculate Moon rise, set and transit
$func->(
$MO,
on_event => sub {
my ($evt, $jd) = @_;
say "$evt: $jd";
},
on_noevent => sub {
my ($evt, $state) = @_; # $STATE_CIRCUMPOLAR or $STATE_NEVER_RISES
say "$evt: $state";
}
);
# alternatively, call the function in list context:
my %res = $func->($MO); # result structure is described below
# calculate civil twilight
twilight(
date => [1989, 3, 23],
phi => 48.1,
lambda => -11.6,
on_event => sub {
my ($evt, $jd) = @_;
lib/Astro/Montenbruck/RiseSet.pm view on Meta::CPAN
Sometimes rise and set happen on different calendar dates. For example, here is the output of C<riseset.pl>
script:
$ perl .\script\riseset.pl --date=1989-03-28 --place=48.1 -11.6 --timezone=UTC
Date : 1989-03-28 UTC
Place : 48N06, 011E35
Time Zone : UTC
rise transit set
Moon 23:34:17 03:23:59 07:10:54
This directly depends on time zone. Since event time is always given as Julian date,
it is not hard to determine correct order of events.
=head1 EXPORT
=head2 FUNCTIONS
=over
=item * L</rst( %args )>
=item * L</riseset( %args )>
=item * L</twilight( %args )>
=back
=head1 FUNCTIONS
=head2 rst( %args )
Returns function for calculating times of rises, sets and transits of celestial bodies. See
L<Astro::Montenbruck::RiseSet::Plarise/rst> .
=head3 Named Arguments
=over
=item *
B<date> - array of B<year> (astronomical, zero-based), B<month> [1..12] and B<day>, [1..31].
=item *
B<phi> - geographical latitude, degrees, positive northward
=item *
B<lambda> - geographical longitude, degrees, positive westward
=back
=head3 Returns
function, which calculates rise, set and transit for a celestial body.
It accepts celestial body identifier as positional argument (see L<Astro::Montenbruck::Ephemeris::Planet>)
and two optional callbacks as named arguments:
=over
=item *
B<on_event($event, $jd> - callback called when the event time is determined. The first argument
is one of: C<$EVT_RISE>, C<$EVT_SET> or C<$EVT_TRANSIT> constants (see L<Astro::Montenbruck::RiseSet::Constants>),
the second - I<Standard Julian Date>.
=item *
B<on_noevent($event, $state> - callback called when the body is I<circumpolar> or I<never rises>.
The first argument is then one of: C<$EVT_RISE>, C<$EVT_SET> or C<$EVT_TRANSIT>, the second - either
C<$STATE_CIRCUMPOLAR> or C<$STATE_NEVER_RISES>.
=back
=head4 List context
When called in list context:
my %res = func();
the function returns a hash:
(
rise => $hashref,
set => $hashref,
transit => $hashref
)
When rise or set takes place, C<$hashref> contains:
{ok => 1, jd => JD}
JD is a Standard Julian Date. Otherwise,
{ok => 0, state => STATE}
STATE is C<$STATE_CIRCUMPOLAR> or C<$STATE_NEVER_RISES>.
=head2 riseset( %args )
Returns function for calculating times of rises and sets of given celestial body. See
L<Astro::Montenbruck::RiseSet::Sunset/riseset_func>.
=head3 Named Arguments
=over
=item *
B<planet> - celestial body identifier (see L<Astro::Montenbruck::Ephemeris::Planet>)
=item *
B<date> - array of B<year> (astronomical, zero-based), B<month> [1..12] and B<day>, [1..31].
=item *
B<phi> - geographical latitude, degrees, positive northward
=item *
B<lambda> - geographical longitude, degrees, positive westward
=back
=head3 Returns
function, which calculates rise and set times of the planet. It accepts and two callbacks as named arguments:
=over
=item *
B<on_event($event, $jd>)
callback called when the event time is determined. The first argument
is one of: C<$EVT_RISE>, C<$EVT_SET> or C<$EVT_TRANSIT> constants (see L<Astro::Montenbruck::RiseSet::Constants>),
the second - I<Standard Julian Date>.
=item *
B<on_noevent($state>
callback called when the body is I<circumpolar> or I<never rises>.
The argument is either C<$STATE_CIRCUMPOLAR> or C<$STATE_NEVER_RISES>.
=back
When called in list context, returns a hash, described in L<rst( %args )/List context>, except
that C<transit> key is missing.
=head2 twilight( %args )
Function for calculating twilight. See L</TWILIGHT EVENT FUNCTION> below.
=head3 Named Arguments
=over
=item *
B<type> - type of twilight, C<$TWILIGHT_NAUTICAL>, C<$TWILIGHT_ASTRO>
or C<$TWILIGHT_CIVIL>, see L<Astro::Montenbruck::RiseSet::Constants/TYPES OF TWILIGHT>.
=item *
B<date> - array of B<year> (astronomical, zero-based), B<month> [1..12] and B<day>, [1..31].
=item *
B<phi> - geographical latitude, degrees, positive northward
=item *
B<lambda> - geographical longitude, degrees, positive westward
=item *
B<on_event> - callback called when the event time is determined. The arguments are:
=over
=item *
Event type, one of C<$EVT_RISE> or C<$EVT_SET>, L<Astro::Montenbruck::RiseSet::Constants/EVENTS>.
The first indicates I<dawn>, the second - I<dusk>.
=item *
time of the event, I<Standard Julian date>.
( run in 1.417 second using v1.01-cache-2.11-cpan-b16cb0d3907 )