|
NAMEAstro::App::Satpass2::FormatValue - Format Astro::App::Satpass2 output as text.SYNOPSISuse strict; use warnings; use Astro::App::Satpass2::FormatValue; use Astro::Coord::ECI; use Astro::Coord::ECI::Moon; use Astro::Coord::ECI::Sun; use Astro::Coord::ECI::Utils qw{ deg2rad }; my $time = time(); my $moon = Astro::Coord::ECI::Moon->universal( $time ); my $sun = Astro::Coord::ECI::Sun->universal( $time ); my $station = Astro::Coord::ECI->new( name => 'White House', )->geodetic( deg2rad(38.8987), # latitude deg2rad(-77.0377), # longitude 17 / 1000); # height above sea level, Km foreach my $body ( $sun, $moon ) { my $fmt = Astro::App::Satpass2::FormatValue->new( data => { body => $body, station => $station, time => $time, } ); print join( ' ', $fmt->date(), $fmt->time(), $fmt->name( width => 10 ), $fmt->azimuth( bearing => 2 ), $fmt->elevation() ), "\n"; } DETAILSThis class is intended to take care of the details of performing field formatting for an Astro::App::Satpass2::Format object, and was actually written to format data for "Template-Toolkit". It is not intended to be used outside one of these, though I suppose it could be.This class is intended to be initialized with a hash containing data in known locations. Not coincidentally, the hash corresponds to the hashes produced by methods of interest in Astro::Coord::ECI and its subclasses. METHODSThis class supports the following public methods.Instantiatornew$fmt = Astro::App::Satpass2::FormatValue->new(); This static method instantiates a new value formatter. It takes as arguments name/value pairs. Because this class has no mutators you must give it all the information it needs to do its job when you instantiate it. The following argument names are recognized:
AccessorsThese are kept to a minimum, since the main purpose of the object is to provide formatting.body $fmt->body(); This accessor returns the contents of the "{body}" key of the original hash passed to the "data" argument when the object was instantiated. It returns a false value if the "{body}" key exists but is not an "Astro::Coord::ECI|Astro::Coord::ECI", or if the key does not exist. This accessor exists because the Astro::App::Satpass2::Format::Template list() method needs to look at the body to decide what to display. MutatorsThese also are kept to a minimum.If called without an argument, all mutators act as accessors, and return the value of the attribute. If called with an argument, they change the attribute (or croak if the new value is invalid), and return their invocant. fixed_width $fmt->fixed_width( 0 ); say 'Fixed-width formatting is ', $fmt->fixed_width() ? 'on' : 'off'; If false, this boolean attribute causes all widths not explicitly specified to default to '', which is the convention for non-fixed-width fields. It can also be set via the "fixed_width" argument to "new()". The default is 1 (i.e. "true"). If called without an argument, this method acts as an accessor, returning the current value. This boolean attribute has a mutator because "Template-Toolkit" needs to modify it, and "Template-Toolkit"-style named arguments can't be used for "clone()" because of the way the interface is designed. title_gravity $fmt->title_gravity( 'bottom' ); say 'Title gravity is ', $fmt->title_gravity(); This attribute specifies how multiline titles are aligned. The possible values are 'top' or 'bottom'. The manifest constants "TITLE_GRAVITY_TOP" and "TITLE_GRAVITY_BOTTOM" are defined to represent these, but they are not exported. If you specify 'bottom', you get an extra empty line above the titles. This is an annoying behavior necessitated by the fact that the first line of the first title has to be inserted into the output before we know how many lines are needed to print all the titles. So we force an extra line with blanks to get the process rolling. This hack means that you do not want to use 'bottom' unless you intend to actually display all the lines of each title. The default is 'top'. This attribute has a mutator because "Template-Toolkit" needs to modify it. TransformationsSome of the methods of interest produce hashes that contain supplementary data. For example, the output of the Astro::Coord::ECI::TLE "pass()" method may contain an <{appulse}> key describing the appulsed body. These methods give access to such data. If the requested data exists, they typically return an "Astro::App::Satpass2::FormatValue" object, though they may return a reference to an array of them, or to an iterator function. If the requested data do not exist, they typically return "undef".appulse my $apls = $fmt->appulse(); This method returns an "Astro::App::Satpass2::FormatValue" object based on the invocant, with the data coming from the "{appulse}" key of the original object's data, augmented with the "{station}" and "{time}" of the original data. bodies my $array_ref = $fmt->bodies(); For reasons that seemed logical at the time, the Astro::App::Satpass2 position() method produces a hash containing the time, some other relevant data, and a "{bodies}" key which contains a reference to an array of all the relevant bodies. This method extracts an array of more-normally-structured "Astro::App::Satpass2::FormatValue" objects which give access to the original bodies. center $center = $fmt->center(); This method returns an "Astro::App::Satpass2::FormatValue" object based on the invocant, with the data coming from the "{center}" key of the original object's data, augmented with the "{station}" and "{time}" of the original data. clone my $clone = $fmt->( %arg ); This method performs a shallow clone the invocant. That is to say, the clone is a separate object, but it shares all contained objects and references with the original object. If any arguments are passed, they are used to initialize the cloned object, instead of the corresponding data from the invocant. earth my $earth = $fmt->earth(); This method returns an "Astro::App::Satpass2::FormatValue" object based on the invocant, with its "{station}" key set to the center of the Earth. events foreach my $event ( @{ $fmt->events() || [] } ) { ... do something with the event ... } This method returns a reference to an array of "Astro::App::Satpass2::FormatValue" objects manufactured out of the contents of the "{events}" key of the invocant's data. reflections $array_ref = $fmt->reflections(); This method returns a reference to an array of "Astro::App::Satpass2::FormatValue" objects which represent the results of calling "$fmt->body()->reflection()", passing it the contents of the "{station}" and "{time}" keys. It will return "undef" if the body does not support this method, or if it is below the horizon or not lit. station my $station = $fmt->station(); This method returns an object identical to the invocant, with the exception that the "{body}" and "{station}" contents are exchanged. With this, $fmt->station()->latitude() (e.g.) gets you the latitude of the observing station, whereas $fmt->latitude() would get you the latitude of the orbiting body. FormattersEach formatter converts the value of a specific key or keys in the "data" hash to text. Typically the conversion is to a fixed-width field unless the "width" argument is non-numeric. If the underlying item does not exist, a user-specified string will be returned instead, or spaces if no string was specified.All the formatter arguments are passed by name: that is, as name/value pairs. Because of the idiosyncrasies of "Template-Toolkit", or because of the author's lack of experience with it, some weirdness has been introduced into what would have been a straightforward signature: * "Template-Toolkit" recognizes special named-argument syntax, and presents the arguments as a hash appended to the argument list. Therefore, if the formatters see a hash as the last argument, that hash will be expanded into a list and prepended to the argument list. Because "Template-Toolkit" does not supply an empty hash if none of its named arguments are seen, you can not pass a hash as the last argument. * "Template-Toolkit" seems to have a strong preference for dealing with arrays as references. But array references are not flattened when passed as arguments. If the caller wants an array reference flattened, it must be made into an instance of Astro::App::Satpass2::Wrap::Array. This is really (I think and hope!) only a problem for whoever writes the code reference that gets passed to the "local_coordinates" argument of "new()" (i.e. me). The summary of all this is that arguments are taken in the following order:
Since arguments are passed by name, you can specify the same argument more than once. If this happens, the "last" specification of the argument is the one taken. One additional complication: for convenience in overriding default titles, if the list of arguments from item "(2)" above ('everything else') has an odd number of elements, 'title' is prepended. The net result of this is that if $title is an "Astro::App::Satpass2::FormatValue" object with "title => 1", something like $title->azimuth( '' ) will produce an empty field of the proper width. The following arguments are accepted by all formatters:
almanac print $fmt->almanac(); The "almanac_hash()" method provided by some subclasses of "Astro::Coord::ECI" returns a hash which includes an "{almanac}" key, which contains various items describing the almanac entry. This method provides access to the contents of the "{almanac}" key. In addition to the standard arguments, it takes the following:
altitude print $fmt->altitude(); This method formats the altitude of the "{body}" object above sea level. In addition to the standard arguments, it takes the following:
angle print $fmt->angle(); This method formats the "{angle}" value, which typically represents an appulse angle. In addition to the standard arguments, it takes the following:
apoapsis print $fmt->apoapsis(); This method formats the apoapsis of the "{body}" object's orbit. In addition to the standard arguments, it takes the following:
apogee print $fmt->apogee(); This method formats the apogee of the "{body}" object's orbit. Yes, this is the same as the apoapsis. In addition to the standard arguments, it takes the following:
argument_of_perigee print $fmt->argument_of_perigee(); This method formats the argument of perigee from the "{body}" object's TLE data. In addition to the standard arguments, it takes the following:
ascending_node print $fmt->ascending_node(); This method formats the ascending node from the "{body}" object's TLE data. In addition to the standard arguments, it takes the following:
azimuth print $fmt->azimuth(); This method formats the azimuth of the "{body}" object as seen from the "{station}" object. In addition to the standard arguments, it takes the following:
b_star_drag print $fmt->b_star_drag(); This method formats the B* drag from the "{body}" object's TLE data.. In addition to the standard arguments, it takes the following:
classification print $fmt->classification(); This method formats the classification of the "{body}" object's TLE data. This will usually be 'U', for 'unclassified'. In addition to the standard arguments, it takes the following:
date print $fmt->date(); This method formats the "{time}" value using the "date_format" template. This is intended to produce the date, without time information. In addition to the standard arguments, it takes the following:
declination print $fmt->declination(); This method formats the declination of the "{body}" object as seen from the "{station}" object. In addition to the standard arguments, it takes the following:
eccentricity print $fmt->eccentricity(); This method formats the eccentricity of the "{body}" object's orbit. In addition to the standard arguments, it takes the following:
effective_date print $fmt->effective_date(); This method formats the effective date of the "{body}" object's TLE data. In addition to the standard arguments, it takes the following:
element_number print $fmt->element_number(); This method formats the number of the "{body}" object's TLE data. This is usually incremented each time a new set is published. In addition to the standard arguments, it takes the following:
elevation print $fmt->elevation(); This method formats the elevation of the "{body}" object above the horizon as seen from the "{station}" object. In addition to the standard arguments, it takes the following:
ephemeris_type print $fmt->ephemeris_type(); This method formats the ephemeris type of the "{body}" object's TLE data. This is supposed to say which model is to be used to calculate the object's position, but in practice is typically 0 or blank. In addition to the standard arguments, it takes the following:
epoch print $fmt->epoch(); This method formats the epoch from the "{body}" object's TLE data. In addition to the standard arguments, it takes the following:
event print $fmt->event(); This method formats the contents of "{event}", which generally comes from an Astro::Coord::ECI::TLE "pass()" calculation. In addition to the standard arguments, it takes the following:
first_derivative print $fmt->first_derivative(); This method formats the first derivative from the "{body}" object's TLE data. The units are actually angle per minute squared, but this formatter treats them as angle. That is, it will give you output in radians per minute squared if you so desire, but not in radians per second squared. In addition to the standard arguments, it takes the following:
fraction_lit print $fmt->fraction_lit(); This method formats the fraction of the "{body}" object which is lit. This is only available if that object supports the "phase()" method. In addition to the standard arguments, it takes the following:
illumination print $fmt->illumination(); This method formats the contents of "{illumination}", which generally comes from an Astro::Coord::ECI::TLE "pass()" calculation, though it is also present if the template calls "data.bodies()". If the satellite is above the horizon, the illumination returned by "bodies()" is the same as that provided by the pass calculation. Prior to version 0.019_01, nothing was returned if the satellite was below the horizon. Beginning with version 0.019_01, the satellite will be shown as either lit or shadowed if it is below the horizon. In addition to the standard arguments, it takes the following:
inclination print $fmt->inclination(); This method formats the orbital inclination from the "{body}" object's TLE data. In addition to the standard arguments, it takes the following:
inertial print $fmt->inertial() This method formats the "inertial" attribute of the "{body}" object, as 0 if the attribute is false, or 1 if it is true. In addition to the standard arguments, it takes the following:
international print $fmt->international(); This method formats the international launch designator from the "{body}" object's TLE data. In addition to the standard arguments, it takes the following:
latitude print $fmt->latitude(); This method formats the latitude of the "{body}" object. In addition to the standard arguments, it takes the following:
list print $fmt->list(); This method formats the object as specified by the "list_formatter" argument when the object was initialized. It has no arguments of its own, but will pass through any arguments given to the methods it calls. See local_coord() below for details. local_coord print $fmt->local_coord(); This method formats the local coordinates as specified by the "local_coordinates" argument when the object was initialized. It has no arguments of its own, but will pass through any arguments given to the methods it calls. You can pass arguments selectively by specifying them as a hash - for example $fmt->local_coord( title => { azimuth => 'azimuth', elevation => 'elevation', }, ); Scalar arguments will be passed to all called methods, except for "append", which will be appended to the entire formatted value. longitude print $fmt->longitude(); This method formats the longitude of the "{body}" object. In addition to the standard arguments, it takes the following:
magnitude print $fmt->magnitude(); This method formats the contents of "{data}{magnitude}", which generally represents the magnitude of an Iridium flare. If "{magnitude}" is undefined but the body supports the "magnitude()" method, the body time is set to the contents of "{time}", and then "$body->magnitude( $station )" is called. In addition to the standard arguments, it takes the following:
maidenhead print $fmt->maidenhead(); This method formats the Maidenhead Grid Locator position of the "{body}" object. In addition to the standard arguments, it takes the following:
mean_anomaly print $fmt->mean_anomaly(); This method formats the mean anomaly from the "{body}" object's TLE data. In addition to the standard arguments, it takes the following:
mean_motion print $fmt->mean_motion(); This method formats the mean motion from the "{body}" object's TLE data. The units are actually angle per minute, but this formatter treats them as angle. That is, it will give you output in radians per minute if you so desire, but not in radians per second. In addition to the standard arguments, it takes the following:
mma print $fmt->mma(); This method formats the contents of "{mma}", which generally indicates the flaring antenna for an Iridium flare. In addition to the standard arguments, it takes the following:
name print $fmt->name(); This method formats the name of the "{body}" object. If the name is missing and you specify "missing => 'oid'" the OID will be displayed instead. In addition to the standard arguments, it takes the following:
oid print $fmt->oid(); This method formats the OID of the "{body}" object. In addition to the standard arguments, it takes the following:
operational print $fmt->operational(); This method formats the operational status of the "{body}" object. This is generally only available if the object represents an Iridium satellite. In addition to the standard arguments, it takes the following:
periapsis print $fmt->periapsis(); This method formats the periapsis of the "{body}" object's orbit. In addition to the standard arguments, it takes the following:
perigee print $fmt->perigee(); This method formats the perigee of the "{body}" object's orbit. Yes, this is the same as the periapsis. In addition to the standard arguments, it takes the following:
period print $fmt->period(); This method formats the period of the "{body}" object's orbit. In addition to the standard arguments, it takes the following:
phase print $fmt->phase(); This method formats the phase of the "{body}" object. This is only available if that object supports the "phase()" method. In addition to the standard arguments, it takes the following:
range print $fmt->range(); This method formats the distance of the "{body}" object from the "{station}" object. In addition to the standard arguments, it takes the following:
revolutions_at_epoch print $fmt->revolutions_at_epoch(); This method formats the revolutions at epoch from the "{body}" object's TLE data. In addition to the standard arguments, it takes the following:
right_ascension print $fmt->right_ascension(); This method formats the right ascension of the "{body}" object as seen from the "{station}" object. In addition to the standard arguments, it takes the following:
second_derivative print $fmt->second_derivative(); This method formats the second derivative from the "{body}" object's TLE data. The units are actually angle per minute cubed, but this formatter treats them as angle. That is, it will give you output in radians per minute cubed if you so desire, but not in radians per second cubed. In addition to the standard arguments, it takes the following:
semimajor print $fmt->semimajor(); This method formats the semimajor axis of the "{body}" object's orbit, calculated using that object's "semimajor()" method. In addition to the standard arguments, it takes the following:
semiminor print $fmt->semiminor(); This method formats the semiminor axis of the "{body}" object's orbit, calculated using that object's "semiminor()" method. In addition to the standard arguments, it takes the following:
status print $fmt->status(); This method formats the contents of "{status}", which usually come from the Astro::App::Satpass2 "position()" method. In addition to the standard arguments, it takes the following:
time print $fmt->time(); This method formats the "{time}" value using the "time_format" template. This is intended to produce the time, without date information. In addition to the standard arguments, it takes the following:
tle print $fmt->tle(); This method formats the TLE data from the "{body}" object. Unlike the other formatters, which produce a fixed-width string, this formatter produces a block of text, whatever is contained by the "{body}" object's "tle" attribute if any. type print $fmt->type(); This method formats the contents of "{type}". This usually comes from the "flare()" method, and says whether the flare occurred in the am, day, or pm. In addition to the standard arguments, it takes the following:
Title ControlTitles can consist of multiple lines, wrapped with Text::Wrap. The display is 'top-heavy', meaning that the column titles are justified to the top.Nothing special needs to be done to get the first line, other than to initialize the object "title => 1". To get all the lines, you need to use a "while" loop, calling "more_title_lines()" in the test. When this returns false you must exit the loop, otherwise you loop infinitely. is_valid_title_gravity Returns a true value if the argument is a valid title gravity setting, and a false value otherwise. Can be called as a static method, or even a subroutine, though it is not exported. more_title_lines my $fmt = Astro::App::Satpass2::Format->new( title => 1 ); while ( $fmt->more_title_lines() ) { print join( ' ', $fmt->azimuth( title => 'Azimuth of object', bearing => 2 ), $fmt->elevation( title => 'Elevation of object' ), ), "\n"; } This method returns true until there are no more lines of title to display. It also increments the internal line counter causing the next line of title to be displayed. reset_title_lines my $fmt->reset_title_lines(); This method resets the title line logic to its original state. You will not normally need to call this unless you want to display titles more than once and you have previously exited a "more_title_lines()" loop prematurely. Adding format effectorsadd_formatter_method$fmt->add_formatter_method( ... ); This experimental method takes as its arguments one or more Astro::App::Satpass2::FormatValue::Formatter objects, and makes them available for use in formatting values. An exception will be thrown if you try to replace an existing formatter, whether it is built-in or previously added with this method. It is not anticipated that the user will need to call this directly. Instead the formatter object will call it on the user's behalf. The whole idea of custom format effectors is highly experimental, and should be considered undocumented and subject to change without notice. UNITSMost of the format effectors format a quantity that is measured in some physical units; that is, kilometers, feet, seconds, or whatever. The "units=" argument can be used to specify the displayed units for the field. This mechanism has been subverted in a couple cases to select among the representations of items that have more than one representation, even when the different representations are not, strictly speaking, physical units.Each format effector that has physical units has an associated dimension, which determines which units are valid for it. The dimension specifies units, synonyms for canonical units, and the default units, though the individual format effector can have its own default (e.g. right_ascension). Typically the default field widths and decimal places are appropriate for the default units, so if you specify different units you should probably specify the field width and decimal places as well. The dimensions are: almanac_pseudo_unitsThe first example is a case where the units mechanism was subverted to select among alternate representations, rather than to convert between physical units. The possible pseudo-units are:"description" = the text description of the event; "event" = the generic name of the event (e.g. 'horizon' for rise or set); "detail" = the numeric event detail, whose meaning depends on the event (e.g. for 'horizon', 1 is rise and 0 is set). The default is 'description'. angle_unitsThis dimension represents a geometric angle. The possible units are:"bearing" = a compass bearing; "decimal" = a synonym for "degrees"; "degrees" = angle in decimal degrees; "radians" = angle in radians; "phase" = name of phase ('new', 'waxing crescent', and so on); "right_ascension" = angle in hours, minutes, and seconds of right ascension. When the angle units are specified as "units => 'bearing'", the precision of the bearing is specified by the "bearing" argument. That is, "bearing => 1" gets you the cardinal points ("N", "E", "S" and "W"), "bearing => 2" gets you the semi-cardinal points, and similarly for "bearing => 3". If "bearing" is not specified it defaults to the same value as the "width" argument, or 2 if no width is specified. The net result is that you need to specify the "bearing" argument if you specify "width => ''" and do not like the default of 2. Yes, I could have equivocated on "places", but this seemed more straight forward. The default is normally degrees, though this is overridden for right_ascension. dimensionlessA few displayed quantities are simply numbers, having no associated physical dimension. These can be specified as:"percent" = display as a percentage value, without the trailing '%'; "unity" = display unaltered. The default is "unity". durationThis dimension represents a span of time, such as an orbital period. The units are:"composite" = days hours:minutes:seconds.fraction; "days" = duration in days and fractions of days; "hours" = duration in hours and fractions of hours; "minutes" = duration in minutes and fractions of minutes; "seconds" = duration in seconds and fractions of seconds. The default is "composite". event_pseudo_unitsLike almanac_pseudo_units, this is not a physical dimension, just a way of selecting different representations. The units are:"integer" = event number (see Astro::Coord::ECI::TLE); "localized" = localized event name; "string" = unlocalized event name. The default is "localized". lengthThis dimension represents lengths and distances. The possible units are:"feet" = US/British feet; "ft" = synonym for 'feet'; "kilometers" = standard kilometers; "km" = synonym for kilometers; "meters" = standard meters; "m" = synonym for 'meters'; "miles" = statute miles. The default is "kilometers". string_pseudo_unitsLike almanac_pseudo_units, this is not a physical dimension, just a way of selecting different representations. The units are:"lower_case" = all lower case; "string" = the unmodified string; "title_case" = lower case, with initial letters upper case, "upper_case" = all upper case. time_unitsThis dimension represents time. The possible units are:"days_since_epoch" = the number of days and fractions thereof since the epoch of the body (undefined if there is no epoch); "gmt" = GMT; "julian" = Julian day (implies GMT -- you may want to set the "places" argument for this); "local" = local time (actually, whatever zone the time formatter is set to); "universal" = an alias for "gmt"; "z" = an alias for "gmt"; "zulu" = an alias for "gmt". The default is "local". SUPPORTSupport is by the author. Please file bug reports at <https://rt.cpan.org/Public/Dist/Display.html?Name=Astro-App-Satpass2>, <https://github.com/trwyant/perl-Astro-App-Satpass2/issues>, or in electronic mail to the author.AUTHORThomas R. Wyant, III wyant at cpan dot orgCOPYRIGHT AND LICENSECopyright (C) 2010-2021 by Thomas R. Wyant, IIIThis program is free software; you can redistribute it and/or modify it under the same terms as Perl 5.10.0. For more details, see the full text of the licenses in the directory LICENSES. This program is distributed in the hope that it will be useful, but without any warranty; without even the implied warranty of merchantability or fitness for a particular purpose.
Visit the GSP FreeBSD Man Page Interface. |