| Geo-Sun documentation | Contained in the Geo-Sun distribution. |
Geo::Sun - Calculates the Geodetic Position of the Sun over the Surface of the Earth
use Geo::Sun; my $gs=Geo::Sun->new; #isa Geo::Sun my $point=$gs->set_datetime(DateTime->now)->point; #Full OO interface printf "Point isa %s\n", ref($point); #isa GPS::Point printf "Latitude: %s, Longitude: %s\n", $point->latlon;
The Geo::Sun package calculates the position of the Sun over the Earth. The user method point_dt takes a DateTime object as a parameter and returns a GPS::Point which is the point on the earth where the Sun is directly over at the given time.
The Geo::Sun package is a wrapper around Astro::Coord::ECI::Sun with a user friendly interface.
use Geo::Sun; my $gs=Geo::Sun->new; printf "Lat: %s, Lon: %s\n", $gs->point->latlon;
my $gs=Geo::Sun->new;
Returns a GPS::Point for the location of the sun at the current datetime.
my $point=$gs->point; my $point=$gs->set_datetime(DateTime->now)->point;
Set the current datetime and returns a GPS::Point
my $point=$gs->point_dt($datetime);
Implemented as
my $point=$gs->set_datetime($datetime)->point;
Sets or returns the current datetime which is a DateTime object. The default is DateTime->now.
Sets datetime returns self
Recalculates the point when the DateTime is changed.
Override this method if you want to calculate something when the point changes
Sets or returns the Astro::Coord::ECI::Sun object.
my $sun=$gs->sun;
Set or returns the Geo::Ellipsoids object.
my $ellipsoid=$gs->ellipsoid; #WGS84
Please send to the geo-perl email list.
Try the geo-perl email list.
Calculations are only good to about 3 decimal places.
Michael R. Davis
CPAN ID: MRDVT
STOP, LLC
domain=>stopllc,tld=>com,account=>mdavis
http://www.stopllc.com/
This program is free software licensed under the...
The BSD License
The full text of the license can be found in the LICENSE file included with this module.
| Geo-Sun documentation | Contained in the Geo-Sun distribution. |
package Geo::Sun; use strict; use warnings; use Astro::Coord::ECI::Sun; use DateTime; use Geo::Constants qw{PI}; use Geo::Functions qw{deg_rad}; use Geo::Ellipsoids; use GPS::Point; BEGIN { use vars qw($VERSION); $VERSION = '0.04'; }
sub new { my $this = shift(); my $class = ref($this) || $this; my $self = {}; bless $self, $class; $self->initialize(@_); return $self; }
sub initialize { my $self=shift; %$self=@_; $self->sun(Astro::Coord::ECI::Sun->new) unless ref($self->sun) eq "Astro::Coord::ECI::Sun"; $self->ellipsoid(Geo::Ellipsoids->new) unless ref($self->ellipsoid) eq "Geo::Ellipsoids"; if (defined $self->datetime) { $self->point_recalculate; #supports $gs->new(datetime=>$dt) } else { $self->datetime(DateTime->now) } $self->initialize2; #a hook if you need it return $self; } sub initialize2 { my $self=shift; return $self; }
sub point { my $self=shift; return $self->{'point'}; }
sub point_dt { my $self=shift; return $self->set_datetime(@_)->point; }
sub datetime { my $self = shift; if (@_) { $self->{"datetime"}=shift; $self->point_recalculate; } return $self->{"datetime"}; }
sub set_datetime { my $self=shift; $self->datetime(@_) if @_; return $self; }
sub point_recalculate { my $self=shift; my $epoch=$self->datetime->clone->set_time_zone("UTC")->epoch; my ($psi, $lambda, $h) = $self->sun->universal($epoch)->geodetic; #speed is 2 pi distance from the polar axis to the surface #of the earth at latitude divided by 1 day (m/s) my $speed=2 * PI() * $self->ellipsoid->n_rad($psi) * cos($psi) / 24 / 60 / 60; $self->{'point'}=GPS::Point->new( time => $self->sun->universal, #float seconds unix epoch (UTC) lat => deg_rad($psi), #signed decimal degrees lon => deg_rad($lambda), #signed decimal degrees alt => $h * 1000, #meters above the WGS-84 ellipsoid speed => $speed, #is this right #meters/second (over ground) heading => 270, #need real value #degrees clockwise from North mode => 3, #GPS mode 3-D tag => "Geo::Sun", #Name of the GPS message for data ); $self->point_onchange; #a hook if you need it. return $self; }
sub point_onchange { my $self=shift; return $self; }
sub sun { my $self=shift; $self->{'sun'}=shift if @_; return $self->{'sun'}; }
sub ellipsoid { my $self = shift(); $self->{'ellipsoid'}=shift if (@_); return $self->{'ellipsoid'}; }
1;