001    /*
002     *    GeoAPI - Java interfaces for OGC/ISO standards
003     *    http://www.geoapi.org
004     *
005     *    Copyright (C) 2004-2013 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.annotation.UML;
035    import org.opengis.annotation.Draft;
036    import org.opengis.geometry.DirectPosition;
037    import org.opengis.geometry.primitive.CurveBoundary;
038    
039    import static org.opengis.annotation.Obligation.*;
040    import static org.opengis.annotation.Specification.*;
041    
042    
043    /**
044     * Common interface for {@linkplain org.opengis.geometry.primitive.Curve curve} and
045     * {@linkplain org.opengis.geometry.primitive.CurveSegment curve segment}. {@code Curve}
046     * and {@code CurveSegment} both represent sections of curvilinear
047     * geometry, and therefore share a number of operation signatures.
048     *
049     * @author  Martin Desruisseaux (IRD)
050     * @author  Axel Francois (LSIS/Geomatys)
051     * @version 3.1
052     * @since   1.0
053     *
054     * @navassoc - - - DirectPosition
055     * @navassoc 1 - - ParamForPoint
056     * @navassoc 1 - - LineString
057     * @navassoc 1 - - PointArray
058     * @navassoc 1 - - CurveBoundary
059     */
060    @UML(identifier="GM_GenericCurve", specification=ISO_19107)
061    public interface GenericCurve {
062        /**
063         * Returns the direct position of the first point on the {@code GenericCurve}.
064         * This differs from the boundary operator in {@link org.opengis.geometry.primitive.Primitive},
065         * since it returns only the values of this point, not representative objects.
066         *
067         * @return The first point on the {@code GenericCurve}.
068         *
069         * @see #getStartParam()
070         * @see #getEndPoint()
071         */
072        @UML(identifier="startPoint", obligation=MANDATORY, specification=ISO_19107)
073        DirectPosition getStartPoint();
074    
075        /**
076         * Returns the direct position of the last point on the {@code GenericCurve}.
077         * This differs from the boundary operator in {@link org.opengis.geometry.primitive.Primitive},
078         * since it returns only the values of this point, not representative objects.
079         *
080         * @return The last point on the {@code GenericCurve}.
081         *
082         * @see #getEndParam()
083         * @see #getStartPoint()
084         */
085        @UML(identifier="endPoint", obligation=MANDATORY, specification=ISO_19107)
086        DirectPosition getEndPoint();
087    
088        /**
089         * Returns the tangent vector along this {@code GenericCurve} at the passed parameter
090         * value. This vector approximates the derivative of the parameterization of the curve.
091         * The tangent shall be a unit vector (have length 1.0), which is consistent with the
092         * parameterization by arc length.
093         *
094         * @param s The parameter value along this curve.
095         * @return The tangent unit vector.
096         * @unitof Distance
097         *
098         * @see #getStartParam()
099         * @see #getEndParam()
100         */
101        @UML(identifier="tangent", obligation=MANDATORY, specification=ISO_19107)
102        double[] getTangent(double s);
103    
104        /**
105         * Indicates the parameter for the {@linkplain #getStartPoint start point}.
106         * The start parameter of a {@linkplain org.opengis.geometry.primitive.Curve curve} shall always be 0.
107         * For {@linkplain org.opengis.geometry.primitive.CurveSegment curve segments} within a
108         * {@linkplain org.opengis.geometry.primitive.Curve curve}, the start of the
109         * {@linkplain org.opengis.geometry.primitive.CurveSegment curve segment} shall be equal to those of the
110         * {@linkplain org.opengis.geometry.primitive.Curve curve} where this segment begins, so that the
111         * start parameter of any segment (except the first) shall be equal to the end
112         * parameter of the previous segment.
113         *
114         * @return The parameter for the {@linkplain #getStartPoint start point}.
115         * @unitof Distance
116         *
117         * @see #getStartPoint()
118         * @see #getStartConstructiveParam()
119         * @see #getEndParam()
120         * @see #forParam(double)
121         */
122        @UML(identifier="startParam", obligation=MANDATORY, specification=ISO_19107)
123        double getStartParam();
124    
125        /**
126         * Indicates the parameter for the {@linkplain #getEndPoint end point}.
127         * The end parameter of a {@linkplain org.opengis.geometry.primitive.Curve curve} shall always be the arc
128         * length of the curve. For {@linkplain org.opengis.geometry.primitive.CurveSegment curve segments} within a
129         * {@linkplain org.opengis.geometry.primitive.Curve curve}, the end parameters of the
130         * {@linkplain org.opengis.geometry.primitive.CurveSegment curve segment} shall be equal to those of the
131         * {@linkplain org.opengis.geometry.primitive.Curve curve} where this segment ends, so that the
132         * start parameter of any segment (except the first) shall be equal to the end
133         * parameter of the previous segment.
134         *
135         * @return The parameter for the {@linkplain #getEndPoint end point}.
136         * @unitof Distance
137         *
138         * @see #getEndPoint()
139         * @see #getEndConstructiveParam()
140         * @see #getStartParam()
141         * @see #forParam(double)
142         */
143        @UML(identifier="endParam", obligation=MANDATORY, specification=ISO_19107)
144        double getEndParam();
145    
146        /**
147         * Indicates the parameter used in the constructive paramerization for the start point.
148         * There is no assumption that the {@code startConstructiveParam} is less than the
149         * {@code endConstructiveParam}, but the parameterization must be strictly monotonic
150         * (strictly increasing, or strictly decreasing).
151         *
152         * <blockquote><font size=-1>
153         * <b>NOTE:</b> Constructive parameters are often chosen for convenience of
154         * calculation, and seldom have any simple relation to arc distances, which are defined
155         * as the default parameterization. Normally, geometric constructions will use constructive
156         * parameters, as the programmer deems reasonable, and calculate arc length parameters when
157         * queried.
158         * </font></blockquote>
159         *
160         * @return The parameter used in the constructive paramerization for the start point.
161         *
162         * @see #getStartParam()
163         * @see #getEndConstructiveParam()
164         * @see #forConstructiveParam(double)
165         */
166        @UML(identifier="startConstrParam", obligation=MANDATORY, specification=ISO_19107)
167        double getStartConstructiveParam();
168    
169        /**
170         * Indicates the parameter used in the constructive paramerization for the end point.
171         * There is no assumption that the {@code startConstructiveParam} is less than the
172         * {@code endConstructiveParam}, but the parameterization must be strictly monotonic
173         * (strictly increasing, or strictly decreasing).
174         *
175         * <blockquote><font size=-1>
176         * <b>NOTE:</b> Constructive parameters are often chosen for convenience of
177         * calculation, and seldom have any simple relation to arc distances, which are defined
178         * as the default parameterization. Normally, geometric constructions will use constructive
179         * parameters, as the programmer deems reasonable, and calculate arc length parameters when
180         * queried.
181         * </font></blockquote>
182         *
183         * @return The parameter used in the constructive paramerization for the end point.
184         *
185         * @see #getEndParam()
186         * @see #getStartConstructiveParam()
187         * @see #forConstructiveParam(double)
188         */
189        @UML(identifier="endConstrParam", obligation=MANDATORY, specification=ISO_19107)
190        double getEndConstructiveParam();
191    
192        /**
193         * Returns the direct position for a constructive parameter. This method shall be
194         * an alternate representation of the curve as the continuous image of a real number
195         * interval without the restriction that the parameter represents the arc length of the curve,
196         * nor restrictions between a {@linkplain org.opengis.geometry.primitive.Curve curve} and its component
197         * {@linkplain org.opengis.geometry.primitive.CurveSegment curve segments}. The most common use of this
198         * operation is to expose the constructive equations of the underlying curve, especially useful
199         * when that curve is used to construct a parametric surface.
200         *
201         * @param cp The constructive parameter.
202         * @return The direct position for the given constructive parameter.
203         *
204         * @see #getStartConstructiveParam()
205         * @see #getEndConstructiveParam()
206         * @see #forParam(double)
207         */
208        @UML(identifier="constrParam", obligation=MANDATORY, specification=ISO_19107)
209        DirectPosition forConstructiveParam(double cp);
210    
211        /**
212         * Returns the direct position for a parameter. This method shall be the parameterized
213         * representation of the curve as the continuous image of a real number interval. The
214         * method returns the direct position on the {@code GenericCurve} at the distance
215         * passed. The parameterization shall be by arc length, i.e. distance along the
216         * {@code GenericCurve} measured from the start point and added to the start parameter.
217         *
218         * @param s The distance from the start point and added to the start parameter.
219         * @return The direct position for the given parameter.
220         *
221         * @see #getStartParam()
222         * @see #getEndParam()
223         * @see #forConstructiveParam(double)
224         */
225        @UML(identifier="param", obligation=MANDATORY, specification=ISO_19107)
226        DirectPosition forParam(double s);
227    
228        /**
229         * Returns the parameter for this {@code GenericCurve} at the passed direct position.
230         * If the direct position is not on the curve, the nearest point on the curve shall be used.
231         *
232         * @param p The direct position on the curve.
233         * @return The parameter closest to the given position.
234         *
235         * @see #getStartPoint()
236         * @see #getEndPoint()
237         * @see #forParam(double)
238         */
239        @UML(identifier="paramForPoint", obligation=MANDATORY, specification=ISO_19107)
240        ParamForPoint getParamForPoint(DirectPosition p);
241    
242        /**
243         * Returns the length between two points.
244         * The length of a piece of curvilinear geometry shall be a numeric measure of its
245         * length in a coordinate reference system. Since length is an accumulation of distance, its
246         * return value shall be in a unit of measure appropriate for measuring distances. This method
247         * shall return the distance between the two points along the curve. The default values of the
248         * two parameters shall be the start point and the end point, respectively. If either of the
249         * points is not on the curve, then it shall be projected to the nearest {@linkplain DirectPosition
250         * direct position} on the curve before the distance is calculated. If the curve is not simple and
251         * passes through either of the two points more than once, the distance shall be the minimal distance
252         * between the two points on this {@linkplain org.opengis.geometry.primitive.Curve curve}.
253         *
254         * @departure draft
255         *   In the ISO 19107:2003 specification, the arguments were
256         *   {@link org.opengis.geometry.coordinate.Position} objects. However in the ISO 19107:2008
257         *   draft specification, the type has been changed to {@link DirectPosition}.
258         *
259         * @param point1 The first point, or {@code null} for the
260         *               {@linkplain #getStartPoint start point}.
261         * @param point2 The second point, or {@code null} for the
262         *               {@linkplain #getEndPoint end point}.
263         * @return The length between the two specified points.
264         * @unitof Length
265         */
266        @UML(identifier="length", obligation=MANDATORY, specification=ISO_19107)
267        double length(DirectPosition point1, DirectPosition point2);
268    
269        /**
270         * Returns the length between two constructive parameters.
271         * This second form of the method {@code length} shall work directly from the constructive
272         * parameters, allowing the direct conversion between the variables used in parameterization and
273         * constructive parameters.
274         *
275         * Distances between direct positions determined by the default parameterization are simply
276         * the difference of the parameter. The length function also allows for the conversion of the
277         * constructive parameter to the arc length parameter using the following idiom:
278         * <p>
279         * <center><code>
280         * param=length({@linkplain #getStartConstructiveParam startConstructiveParam}, constructiveParam)
281         *       + {@linkplain #getStartParam startParam}
282         * </code></center>
283         *
284         * @param cparam1 The first constructive parameter.
285         * @param cparam2 The second constructive parameter.
286         * @return The length between the two specified constructive parameter.
287         * @unitof Length
288         */
289        @UML(identifier="length", obligation=MANDATORY, specification=ISO_19107)
290        double length(double cparam1, double cparam2);
291    
292        /**
293         * Returns the geometry of the curve topological boundary. If the {@linkplain #getStartPoint()
294         * start point} is not equal to the {@linkplain #getEndPoint() end point}, the boundary is a
295         * two point array. If the start point is equal to the end point, the boundary is an empty array.
296         *
297         * <blockquote><font size=-1><b>NOTE:</b>
298         * The above point array will almost always be two distinct positions, but both
299         * {@linkplain org.opengis.geometry.primitive.Curve curves} and
300         * {@linkplain org.opengis.geometry.primitive.CurveSegment} can be cycles in themselves.
301         * The most likely scenario is that all of the points used will be transients (constructed
302         * to support the return value), except for the start point and end point of the aggregated
303         * curve. These two positions, in the case where the curve is involved in a
304         * {@linkplain org.opengis.geometry.complex.Complex complex}, will be represented as
305         * {@linkplain org.opengis.geometry.primitive.Point points} in the same complex.
306         * </font></blockquote>
307         *
308         * @return The sets of positions on the boundary.
309         */
310        @Draft
311        @UML(identifier="boundary", obligation=MANDATORY, specification=ISO_19107)
312        CurveBoundary getBoundary();
313    
314        /**
315         * Returns an ordered array of point values that lie on the curve.
316         * In most cases, these will be related to control points used in the construction of the segment.
317         *
318         * <blockquote><font size=-1><b>NOTE:</b>
319         * The control points of a curve segment are used to control its shape, and are not always on the
320         * curve segment itself. For example in a spline curve, the curve segment is given as a weighted
321         * vector sum of the control points. Each weight function will have a maximum within the
322         * constructive parameter interval, which will roughly correspond to the point on the curve
323         * where it passes closest that the corresponding control point. These points, the values of
324         * the curve at the maxima of the weight functions, will be the sample points for the curve
325         * segment.
326         * </font></blockquote>
327         *
328         * @departure easeOfUse
329         *   The ISO 19107 specification returns an array of {@link org.opengis.geometry.primitive.Point}
330         *   object. GeoAPI returns a {@link PointArray} object instead, in order to allow deferred point
331         *   creation for implementors, and convenient access to the {@code PointArray} methods for users.
332         *
333         * @return The control points.
334         */
335        @Draft
336        @UML(identifier="samplePoints", obligation=MANDATORY, specification=ISO_19107)
337        PointArray getSamplePoints();
338    
339        /**
340         * Constructs a line string (sequence of line segments) where the control points (ends of
341         * the segments) lie on this curve. If {@code maxSpacing} is given (not zero), then
342         * the distance between control points along the generated curve shall be not more than
343         * {@code maxSpacing}. If {@code maxOffset} is given (not zero), the distance
344         * between generated curve at any point and the original curve shall not be more than the
345         * {@code maxOffset}. If both parameters are set, then both criteria shall be met.
346         * If the original control points of the curve lie on the curve, then they shall be included
347         * in the returned {@linkplain LineString line string}'s control points. If both parameters are
348         * set to zero, then the line string returned shall be constructed from the control points of the
349         * original curve.
350         *
351         * <blockquote><font size=-1>
352         * <b>NOTE:</b> This function is useful in creating linear approximations of the
353         * curve for simple actions such as display. It is often referred to as a "stroked curve".
354         * For this purpose, the {@code maxOffset} version is useful in maintaining a minimal
355         * representation of the curve appropriate for the display device being targeted. This
356         * function is also useful in preparing to transform a curve from one coordinate reference
357         * system to another by transforming its control points. In this case, the
358         * {@code maxSpacing} version is more appropriate. Allowing both parameters to default
359         * to zero does not seem to have any useful geographic nor geometric interpretation unless
360         * further information is known about how the curves were constructed.
361         * </font></blockquote>
362         *
363         * @param maxSpacing The maximal distance between control points along the generated curve,
364         *                   or 0 for no constraint.
365         * @param maxOffset  The maximal distance between generated curve at any point and the original
366         *                   curve, or 0 for no constraint.
367         * @return The an approximation of this curve as a line string.
368         * @unitof Distance (for arguments)
369         */
370        @UML(identifier="asLineString", obligation=MANDATORY, specification=ISO_19107)
371        LineString asLineString(double maxSpacing, double maxOffset);
372    
373        /**
374         * Reverses the orientation of the parameterizations of the curve. In most cases this involves
375         * a reversal of the ordering of parameters in the curve segments, and a reversal of the order
376         * of the segments with a curve.
377         *
378         * @return The reverse of the curve.
379         */
380        @Draft
381        @UML(identifier="reverse", obligation=MANDATORY, specification=ISO_19107)
382        GenericCurve reverse();
383    }