001    package edu.nrao.sss.astronomy;
002    
003    import java.util.Date;
004    
005    import edu.nrao.sss.geom.EarthPosition;
006    import edu.nrao.sss.geom.SphericalPosition;
007    import edu.nrao.sss.measure.Angle;
008    import edu.nrao.sss.measure.Distance;
009    import edu.nrao.sss.measure.Latitude;
010    import edu.nrao.sss.measure.LocalSiderealTime;
011    import edu.nrao.sss.measure.Longitude;
012    
013    /**
014     * A point on the celestial sphere.
015     * <p>
016     * <b>Version Info:</b>
017     * <table style="margin-left:2em">
018     *   <tr><td>$Revision: 1156 $</td></tr>
019     *   <tr><td>$Date: 2008-03-12 11:43:13 -0600 (Wed, 12 Mar 2008) $</td></tr>
020     *   <tr><td>$Author: dharland $ (last person to modify)</td></tr>
021     * </table></p>
022     * 
023     * @author David M. Harland
024     * @since 2007-04-13
025     */
026    public interface SkyPosition
027      extends SphericalPosition
028    {
029      //TODO should validTime be a property?
030    
031      /**
032       * Returns <i>true</i> if this position has different properties at time T
033       * than it does at time U &ne; T.
034       * <p>
035       * The determination of motion will be made with respect to the
036       * coordinate system in which this position is expressed.
037       * For example, a position that is expressed in the equatorial system,
038       * and that is holding steady at its position in that system, will said
039       * to be not moving, even though in other coordinate systems it may be
040       * moving quite rapidly.</p>
041       * 
042       * @return <i>true</i> if this position is moving.
043       */
044      public boolean isMoving();
045      
046      /**
047       * Returns the longitude of this position at the given point in time.
048       * <p>
049       * Classes that implement this interface are free to choose whether to return
050       * a reference to their internal longitudes, or to provide copies thereof.
051       * This means that clients of this interface should not write code that
052       * manipulates the returned object and relies on those changes being
053       * reflected in this object, unless they know they are using an
054       * implementation that returns internal references.</p>
055       * 
056       * @param time the point in time for which the longitude is sought.
057       * 
058       * @return the longitude at the given point in time.
059       */
060      public Longitude getLongitude(Date time);
061    
062      /**
063       * Returns the latitude of this position at the given point in time.
064       * <p>
065       * Classes that implement this interface are free to choose whether to return
066       * a reference to their internal latitudes, or to provide copies thereof.
067       * This means that clients of this interface should not write code that
068       * manipulates the returned object and relies on those changes being
069       * reflected in this object, unless they know they are using an
070       * implementation that returns internal references.</p>
071       * 
072       * @param time the point in time for which the latitude is sought.
073       * 
074       * @return the latitude at the given point in time.
075       */
076      public Latitude getLatitude(Date time);
077    
078      /**
079       * Returns the distance of this position at the given point in time.
080       * <p>
081       * Classes that implement this interface are free to choose whether to return
082       * a reference to their internal distances, or to provide copies thereof.
083       * This means that clients of this interface should not write code that
084       * manipulates the returned object and relies on those changes being
085       * reflected in this object, unless they know they are using an
086       * implementation that returns internal references.</p>
087       * 
088       * @param time the point in time for which the distance is sought.
089       * 
090       * @return the distance at the given point in time.
091       */
092      public Distance getDistance(Date time);
093    
094      //NOTE TO PROGRAMMERS: We intentionally have no set-methods for the
095      //     coordinate system and epoch.  Some of the implementations wish
096      //     to control these properties and not allow clients to set them.
097      
098      /**
099       * Returns the coordinate system to use when interpreting the
100       * latitude and longitude values of this position.
101       * 
102       * @return the system of latitude and longitude used by this position.
103       */
104      public CelestialCoordinateSystem getCoordinateSystem();
105      
106      /**
107       * Returns the epoch on which this position is based.
108       * @return the epoch on which this position is based.
109       */
110      public Epoch getEpoch();
111      
112      /**
113       * Returns the origin of this position's information.
114       * @return the origin of this position's information.
115       */
116      public String getOriginOfInformation();
117    
118      /**
119       * Provides a hint as to how this position stores its information.
120       * 
121       * @return a hint as to how this position stores its information.
122       */
123      public SkyPositionType getType();
124      
125      /**
126       * Calculates current angular separation between this position and
127       * {@code other} at the given time.
128       * <p>
129       * The distances of the positions from the center of the sphere are
130       * <i>not</i> considered.  The returned angle is the smallest possible
131       * such angle.  It is the angular size of the arc of a great circle that
132       * passes through both the ray from the orgin to this position and the
133       * ray from the origin to {@code other}.</p>
134       * <p>
135       * The returned value is never negative.  This means that the returned
136       * angle does not contain directional information.  That is, the angle
137       * from A to B is exactly equal to the angle from B to A.</p>
138       *  
139       * @param other a position from which this one is separated by the
140       *              returned angle.
141       * 
142       * @param time the point in time for which the separation is sought.
143       *              
144       * @return the angle of separation between this position and {@code other}.
145       */
146      public Angle getAngularSeparation(SphericalPosition other, Date time);
147    
148      /**
149       * Returns a new position expressed in the given coordinate system and epoch
150       * that is equivalent to this position.
151       * This position is not changed by this method.
152       * 
153       * @param system
154       *   the celestial coordinate system of the returned position.
155       *    
156       * @param epoch
157       *   the epoch of the returned position.
158       *   
159       * @param observer
160       *   the location of the observer.  This value is used almost exclusively for
161       *   conversions to or from the <tt>HORIZONTAL</tt> (az/el) coordinate system.
162       *   If a given conversion does not require this parameter, a <i>null</i>
163       *   value will do no harm.
164       *   
165       * @param lst
166       *   the local sidereal time at the observer's location.  This parameter
167       *   serves two purposes.  First, it is integral in conversions to or from
168       *   the <tt>HORIZONTAL</tt> (az/el) coordinate system.  Second, even for
169       *   conversions that do not depend on the observer's location, the conversion
170       *   method will use the UTC time represented by this LST to determine the
171       *   exact location of this position before converting it to another
172       *   system.  When used this way the location associated with the LST is
173       *   immaterial.  If this value is <i>null</i> it will be replaced with
174       *   the current time.  Using a <i>null</i> value is not recommended when
175       *   dealing with the <tt>HORIZONTAL</tt> system because the LST may not
176       *   be for the location of interest.
177       *   
178       * @return
179       *   a new position with a coordinate system of {@code system}, and
180       *   epoch of {@code epoch}, and coordinates that represent a conversion
181       *   from those of this position.
182       *   
183       * @throws CoordinateConversionException
184       *   if anything goes wrong with the conversion.
185       */
186      public SkyPosition toPosition(CelestialCoordinateSystem system,
187                                    Epoch                     epoch,
188                                    EarthPosition             observer,
189                                    LocalSiderealTime         lst)
190        throws CoordinateConversionException;
191      
192      /**
193       * Returns a new position expressed in the given coordinate system and epoch
194       * that is equivalent to this position.
195       * This position is not changed by this method.
196       * 
197       * @param system
198       *   the celestial coordinate system of the returned position.
199       *    
200       * @param epoch
201       *   the epoch of the returned position.
202       *   
203       * @param observer
204       *   the location of the observer.  This value is used almost exclusively for
205       *   conversions to or from the <tt>HORIZONTAL</tt> (az/el) coordinate system.
206       *   
207       * @param lst
208       *   the local sidereal time at the observer's location.  This parameter
209       *   serves two purposes.  First, it is integral in conversions to or from
210       *   the <tt>HORIZONTAL</tt> (az/el) coordinate system.  Second, even for
211       *   conversions that do not depend on the observer's location, the conversion
212       *   method will use the UTC time represented by this LST to determine the
213       *   exact location of this position before converting it to another
214       *   system.  When used this way the location associated with the LST is
215       *   immaterial.  If this value is <i>null</i> it will be replaced with
216       *   the current time.  Using a <i>null</i> value is not recommended when
217       *   dealing with the <tt>HORIZONTAL</tt> system because the LST may not
218       *   be for the location of interest.
219       *   
220       * @param converter
221       *   the converter used to perform the transformation.
222       * 
223       * @return
224       *   a new position with a coordinate system of {@code system}, and
225       *   epoch of {@code epoch}, and coordinates that represent a conversion
226       *   from those of this position.
227       *   
228       * @throws CoordinateConversionException
229       *   if anything goes wrong with the conversion.
230       */
231      public SkyPosition toPosition(CelestialCoordinateSystem    system,
232                                    Epoch                        epoch,
233                                    EarthPosition                observer,
234                                    LocalSiderealTime            lst,
235                                    CelestialCoordinateConverter converter)
236        throws CoordinateConversionException;
237      
238      /**
239       * Returns a copy of this sky position.
240       * @return a copy of this sky position.
241       */
242      public SkyPosition clone();
243    }