001    /*
002     *    GeoAPI - Java interfaces for OGC/ISO standards
003     *    http://www.geoapi.org
004     *
005     *    Copyright (C) 2005-2012 Open Geospatial Consortium, Inc.
006     *    All Rights Reserved. http://www.opengeospatial.org/ogc/legal
007     *
008     *    Permission to use, copy, and modify this software and its documentation, with
009     *    or without modification, for any purpose and without fee or royalty is hereby
010     *    granted, provided that you include the following on ALL copies of the software
011     *    and documentation or portions thereof, including modifications, that you make:
012     *
013     *    1. The full text of this NOTICE in a location viewable to users of the
014     *       redistributed or derivative work.
015     *    2. Notice of any changes or modifications to the OGC files, including the
016     *       date changes were made.
017     *
018     *    THIS SOFTWARE AND DOCUMENTATION IS PROVIDED "AS IS," AND COPYRIGHT HOLDERS MAKE
019     *    NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
020     *    TO, WARRANTIES OF MERCHANTABILITY OR FITNESS FOR ANY PARTICULAR PURPOSE OR THAT
021     *    THE USE OF THE SOFTWARE OR DOCUMENTATION WILL NOT INFRINGE ANY THIRD PARTY
022     *    PATENTS, COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS.
023     *
024     *    COPYRIGHT HOLDERS WILL NOT BE LIABLE FOR ANY DIRECT, INDIRECT, SPECIAL OR
025     *    CONSEQUENTIAL DAMAGES ARISING OUT OF ANY USE OF THE SOFTWARE OR DOCUMENTATION.
026     *
027     *    The name and trademarks of copyright holders may NOT be used in advertising or
028     *    publicity pertaining to the software without specific, written prior permission.
029     *    Title to copyright in this software and any associated documentation will at all
030     *    times remain with copyright holders.
031     */
032    package org.opengis.geometry.coordinate;
033    
034    import org.opengis.geometry.DirectPosition;
035    import org.opengis.geometry.primitive.Curve;
036    import org.opengis.geometry.primitive.Surface;
037    import org.opengis.geometry.primitive.SurfacePatch;
038    import org.opengis.geometry.primitive.CurveInterpolation;
039    import org.opengis.geometry.complex.Complex;
040    import org.opengis.annotation.UML;
041    
042    import static org.opengis.annotation.Obligation.*;
043    import static org.opengis.annotation.Specification.*;
044    
045    
046    /**
047     * The surface patches that make up the parametric curve surfaces.
048     * {@code ParametricCurveSurface} are all continuous families of curves,
049     * given by a constructive function of the form:
050     *
051     * <blockquote>
052     * {@code surface}(<var>s</var>,<var>t</var>):
053     * [<var>a</var>,<var>b</var>]&times;[<var>c</var>,<var>d</var>] &rarr; {@link DirectPosition}
054     * </blockquote>
055     *
056     * By fixing the value of either parameter, we have a one-parameter family of curves.
057     *
058     * <blockquote>
059     * c<sub>t</sub>(<var>s</var>) = c<sub>s</sub>(<var>t</var>) =
060     * {@code surface}(<var>s</var>,<var>t</var>);
061     * </blockquote>
062     *
063     * The functions on {@code ParametricCurveSurface} shall expose these two families of curves. The
064     * first gives us the "horizontal" cross sections c<sub>t</sub>(<var>s</var>), the later the
065     * "vertical" cross sections c<sub>s</sub>(<var>t</var>). The terms "horizontal" and "vertical"
066     * refer to the parameter space and need not be either horizontal or vertical curves in the coordinate
067     * reference system. The table below lists some possible pairs of types for these surface curves
068     * (other representations of these same surfaces are possible).
069     * <p>
070     * <table border="1" cellspacing="0" cellpadding="2">
071     *   <tr bgcolor="#CCCCFF" class="TableHeadingColor">
072     *     <th nowrap>&nbsp;Surface type&nbsp;</th>
073     *     <th nowrap>&nbsp;Horizontal Curve type&nbsp;</th>
074     *     <th nowrap>&nbsp;Vertical curve type&nbsp;</th>
075     *   </tr><tr>
076     *     <td nowrap>&nbsp;{@link Cylinder}&nbsp;</td>
077     *     <td nowrap>&nbsp;Circle, constant radii&nbsp;</td>
078     *     <td nowrap>&nbsp;Line Segment&nbsp;</td>
079     *   </tr><tr>
080     *     <td nowrap>&nbsp;{@link Cone}&nbsp;</td>
081     *     <td nowrap>&nbsp;Circle, decreasing radii&nbsp;</td>
082     *     <td nowrap>&nbsp;Line Segment&nbsp;</td>
083     *   </tr><tr>
084     *     <td nowrap>&nbsp;{@link Sphere}&nbsp;</td>
085     *     <td nowrap>&nbsp;Circle of constant latitude&nbsp;</td>
086     *     <td nowrap>&nbsp;Circle of constant longitude&nbsp;</td>
087     *   </tr><tr>
088     *     <td nowrap>&nbsp;{@link BilinearGrid}&nbsp;</td>
089     *     <td nowrap>&nbsp;Line string&nbsp;</td>
090     *     <td nowrap>&nbsp;Line string&nbsp;</td>
091     *   </tr><tr>
092     *     <td nowrap>&nbsp;{@link BicubicGrid}&nbsp;</td>
093     *     <td nowrap>&nbsp;Cubic spline&nbsp;</td>
094     *     <td nowrap>&nbsp;Cubic spline&nbsp;</td>
095     *   </tr>
096     * </table>
097     * <p>
098     * The two partial derivatives of the surface parameterization, <b>i</b> and <b>j</b> are given by:
099     *
100     * <blockquote>TODO: copy equations there</blockquote>
101     *
102     * and
103     *
104     * <blockquote>TODO: copy equations there</blockquote>
105     *
106     * The default {@linkplain #getUpNormal upNormal} for the surface shall be the vector cross product
107     * of these two curve derivatives when they are both non-zero:
108     *
109     * <blockquote>
110     * <b>k</b> = <b>i</b> &times; <b>j</b>
111     * </blockquote>
112     *
113     * If the coordinate reference system is 2D, then the vector <b>k</b> extends the local coordinate
114     * system by supplying an "upward" elevation vector. In this case the vector basis
115     * (<b>i</b>,&nbsp;<b>j</b>) must be a right hand system, that is to say, the oriented angle from
116     * <b>i</b> to <b>j</b> must be less than 180&deg;. This gives a right-handed "moving frame" of local
117     * coordinate axes given by &lt;<b>i</b>, <b>j</b>&gt;. A moving frame is defined to be a continuous
118     * function from the geometric object to a basis for the local tangent space of that object. For
119     * curves, this is the derivative of the curve, the local tangent. For surfaces, this is a local
120     * pair of tangents. Parameterized curve surfaces have a natural moving frame and it shall be used
121     * as defined in this paragraph to define the upNormal of the surface.
122     *
123     * <blockquote><font size=2>
124     * <strong>NOTE:</strong> The existence of a viable moving frame is the definition of "orientable"
125     * manifold. This is why the existence of a continuous {@linkplain #getUpNormal upNormal} implies
126     * that the surface is orientable. Non-orientable surfaces, such as the Möbius band and Klein bottle
127     * are counter-intuitive. {@link Surface} forbids their use in application schemas conforming to
128     * the ISO 19107 standard. Klein bottles cannot even be constructed in 3D space, but require 4D
129     * space for non-singular representations.
130     * </font></blockquote>
131     *
132     * @version <A HREF="http://www.opengeospatial.org/standards/as">ISO 19107</A>
133     * @author Martin Desruisseaux (IRD)
134     * @since GeoAPI 2.0
135     */
136    @UML(identifier="GM_ParametricCurveSurface", specification=ISO_19107)
137    public interface ParametricCurveSurface extends SurfacePatch {
138        /**
139         * Indicates the type of surface curves used to traverse the surface horizontally
140         * with respect to the parameter <var>s</var>.
141         */
142        @UML(identifier="horizontalCurveType", obligation=MANDATORY, specification=ISO_19107)
143        CurveInterpolation getHorizontalCurveType();
144    
145        /**
146         * Indicates the type of surface curves used to traverse the surface vertically with
147         * respect to the parameter <var>t</var>.
148         */
149        @UML(identifier="verticalCurveType", obligation=MANDATORY, specification=ISO_19107)
150        CurveInterpolation getVerticalCurveType();
151    
152        /**
153         * Constructs a curve that traverses the surface horizontally with respect to the parameter
154         * <var>s</var>. This curve holds the parameter <var>t</var> constant.
155         *
156         * <blockquote><font size=2>
157         * <strong>NOTE:</strong>
158         * The curve returned by this function or by the corresponding vertical curve function, are
159         * normally not part of any {@linkplain Complex complex} to which this surface is included.
160         * These are, in general, calculated transient values. The exceptions to this may occur at
161         * the extremes of the parameter space. The boundaries of the parameter space support for
162         * the surface map normally to the boundaries of the target surfaces.
163         * </font></blockquote>
164         *
165         * @param  t The <var>t</var> value to hold constant.
166         * @return The curve that traverses the surface.
167         */
168        @UML(identifier="horizontalCurve", obligation=MANDATORY, specification=ISO_19107)
169        Curve horizontalCurve(double t);
170    
171        /**
172         * Constructs a curve that traverses the surface vertically with respect to the parameter
173         * <var>t</var>. This curve holds the parameter <var>s</var> constant.
174         *
175         * @param  s The <var>s</var> value to hold constant.
176         * @return The curve that traverses the surface.
177         */
178        @UML(identifier="verticalCurve", obligation=MANDATORY, specification=ISO_19107)
179        Curve verticalCurve(double s);
180    
181        /**
182         * Traverses the surface both vertically and horizontally.
183         */
184        @UML(identifier="surface", obligation=MANDATORY, specification=ISO_19107)
185        DirectPosition surface(double s, double t);
186    }