001    /*
002     *    GeoAPI - Java interfaces for OGC/ISO standards
003     *    http://www.geoapi.org
004     *
005     *    Copyright (C) 2004-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 java.util.List;
035    import java.util.Set;
036    import org.opengis.referencing.crs.CoordinateReferenceSystem;
037    import org.opengis.geometry.DirectPosition;
038    import org.opengis.geometry.Envelope;
039    import org.opengis.geometry.MismatchedDimensionException;
040    import org.opengis.geometry.MismatchedReferenceSystemException;
041    import org.opengis.geometry.aggregate.MultiPrimitive;
042    import org.opengis.geometry.primitive.Surface;
043    import org.opengis.geometry.primitive.SurfaceBoundary;
044    import org.opengis.annotation.UML;
045    
046    import static org.opengis.annotation.Obligation.*;
047    import static org.opengis.annotation.Specification.*;
048    
049    
050    /**
051     * A factory of {@linkplain org.opengis.geometry.Geometry geometries}.
052     * All geometries created through this interface will use the
053     * {@linkplain #getCoordinateReferenceSystem factory's coordinate reference system}.
054     * Creating geometries in a different CRS may requires a different instance of
055     * {@code GeometryFactory}.
056     *
057     * @version <A HREF="http://www.opengeospatial.org/standards/as">ISO 19107</A>
058     * @author Martin Desruisseaux (IRD)
059     * @since GeoAPI 1.0
060     */
061    public interface GeometryFactory {
062        /**
063         * Returns the coordinate reference system in use for all
064         * {@linkplain org.opengis.geometry.Geometry geometries}
065         * to be created through this interface.
066         */
067        CoordinateReferenceSystem getCoordinateReferenceSystem();
068    
069        /**
070         * Create a direct position with empty coordinates.
071         * @deprecated Moved to PositionFactory
072         */
073        @Deprecated
074        DirectPosition createDirectPosition();
075    
076        /**
077         * Create a direct position at the specified location specified by coordinates.
078         * @deprecated Moved to PositionFactory
079         */
080        @Deprecated
081        DirectPosition createDirectPosition(double[] coordinates);
082    
083        /**
084         * Creates a new Envelope with the given corners.
085         *
086         * @param lowerCorner A coordinate position consisting of all the maximal ordinates for each
087         *                    dimension for all points within the envelope.
088         * @param upperCorner A coordinate position consisting of all the minimal ordinates for each
089         *                    dimension for all points within the envelope.
090         *
091         * @throws MismatchedReferenceSystemException If the coordinate positions don't use
092         *         compatible {@linkplain CoordinateReferenceSystem coordinate reference system}.
093         * @throws MismatchedDimensionException If the coordinate position don't have compatible dimension.
094         */
095        Envelope createEnvelope(DirectPosition lowerCorner, DirectPosition upperCorner)
096                throws MismatchedReferenceSystemException, MismatchedDimensionException;
097    
098        /**
099         * Takes two positions and creates the appropriate line segment joining them.
100         *
101         * @param startPoint The {@linkplain LineSegment#getStartPoint start point}.
102         * @param   endPoint The {@linkplain LineSegment#getEndPoint end point}.
103         *
104         * @throws MismatchedReferenceSystemException If geometric objects given in argument don't
105         *         use compatible {@linkplain CoordinateReferenceSystem coordinate reference system}.
106         * @throws MismatchedDimensionException If geometric objects given in argument don't have
107         *         the expected dimension.
108         */
109        @UML(identifier="GM_LineSegment(GM_Position[2])", obligation=MANDATORY, specification=ISO_19107)
110        LineSegment createLineSegment(Position startPoint, Position endPoint)
111                throws MismatchedReferenceSystemException, MismatchedDimensionException;
112    
113        /**
114         * Takes two or more positions and creates the appropriate line string joining them.
115         *
116         * @throws MismatchedReferenceSystemException If geometric objects given in argument don't
117         *         use compatible {@linkplain CoordinateReferenceSystem coordinate reference system}.
118         * @throws MismatchedDimensionException If geometric objects given in argument don't have
119         *         the expected dimension.
120         */
121        @UML(identifier="GM_LineString(GM_Position[2..n])", obligation=MANDATORY, specification=ISO_19107)
122        LineString createLineString(List<Position> points)
123                throws MismatchedReferenceSystemException, MismatchedDimensionException;
124    
125        /**
126         * Takes two positions and creates the appropriate geodesic joining them.
127         *
128         * @param startPoint The {@linkplain Geodesic#getStartPoint start point}.
129         * @param   endPoint The {@linkplain Geodesic#getEndPoint end point}.
130         *
131         * @throws MismatchedReferenceSystemException If geometric objects given in argument don't
132         *         use compatible {@linkplain CoordinateReferenceSystem coordinate reference system}.
133         * @throws MismatchedDimensionException If geometric objects given in argument don't have
134         *         the expected dimension.
135         */
136        Geodesic createGeodesic(Position startPoint, Position endPoint)
137                throws MismatchedReferenceSystemException, MismatchedDimensionException;
138    
139        /**
140         * Takes two or more positions, interpolates using a geodesic defined from
141         * the geoid (or {@linkplain org.opengis.referencing.datum.Ellipsoid ellipsoid}) of the
142         * {@linkplain org.opengis.referencing.crs.CoordinateReferenceSystem coordinate reference system}
143         * being used, and creates the appropriate geodesic string joining them.
144         *
145         * @throws MismatchedReferenceSystemException If geometric objects given in argument don't
146         *         use compatible {@linkplain CoordinateReferenceSystem coordinate reference system}.
147         * @throws MismatchedDimensionException If geometric objects given in argument don't have
148         *         the expected dimension.
149         */
150        @UML(identifier="GM_GeodesicString(GM_Position[2..n])", obligation=MANDATORY, specification=ISO_19107)
151        GeodesicString createGeodesicString(List<Position> points)
152                throws MismatchedReferenceSystemException, MismatchedDimensionException;
153    
154        /**
155         * Takes three positions and constructs the corresponding arc.
156         *
157         * @param startPoint The {@linkplain Arc#getStartPoint start point}.
158         * @param   midPoint Some point on the arc neither at the start or end.
159         * @param   endPoint The {@linkplain Arc#getEndPoint end point}.
160         *
161         * @throws MismatchedReferenceSystemException If geometric objects given in argument don't
162         *         use compatible {@linkplain CoordinateReferenceSystem coordinate reference system}.
163         * @throws MismatchedDimensionException If geometric objects given in argument don't have
164         *         the expected dimension.
165         */
166        @UML(identifier="GM_Arc(GM_Position[3])", obligation=MANDATORY, specification=ISO_19107)
167        Arc createArc(Position startPoint, Position midPoint, Position endPoint)
168                throws MismatchedReferenceSystemException, MismatchedDimensionException;
169    
170        /**
171         * Takes two positions and the offset of the midpoint of the arc from the midpoint of
172         * the chord, given by a distance and direction, and constructs the corresponding arc.
173         * The midpoint of the resulting arc is given by:
174         *
175         * <blockquote><pre>midPoint = ((startPoint + endPoint)/2.0) + bulge&times;normal</pre></blockquote>
176         *
177         * In 2D coordinate reference systems, the bulge can be given a sign and the normal can be
178         * assumed to be the perpendicular to the line segment between the start and end point of
179         * the arc (the chord of the arc), pointing left. For example if the two points are
180         * <var>P</var><sub>0</sub> = (<var>x</var><sub>0</sub>,&nbsp;<var>y</var><sub>0</sub>) and
181         * <var>P</var><sub>1</sub> = (<var>x</var><sub>1</sub>,&nbsp;<var>y</var><sub>1</sub>), and
182         * the bulge is <var>b</var>, then the vector in the direction of <var>P</var><sub>1</sub>
183         * from <var>P</var><sub>0</sub> is:
184         *
185         * <blockquote>
186         * <b><var>u</var></b> = (<var>u</var><sub>0</sub>,&nbsp;<var>u</var><sub>1</sub>) =
187         * (<var>x</var><sub>1</sub>-<var>x</var><sub>0</sub>,
188         *  <var>y</var><sub>1</sub>-<var>y</var><sub>0</sub>) /
189         * {@link Math#sqrt sqrt}((<var>x</var><sub>1</sub>-<var>x</var><sub>0</sub>)<sup>2</sup> +
190         *                        (<var>y</var><sub>1</sub>-<var>y</var><sub>0</sub>)<sup>2</sup>)
191         * </blockquote>
192         *
193         * To complete a right-handed local coordinate system {<b>u</b>,<b>v</b>}, the two vectors
194         * must have a vector dot product of zero and a vector cross product of 1. By inspection,
195         * the leftward normal to complete the pair is:
196         *
197         * <blockquote>
198         * <b><var>v</var></b> = (<var>v</var><sub>0</sub>,&nbsp;<var>v</var><sub>1</sub>) =
199         *                      (-<var>u</var><sub>1</sub>,&nbsp;<var>u</var><sub>0</sub>)
200         * </blockquote>
201         *
202         * The midpoint of the arc, which is the midpoint of the chord offset by the bulge, becomes:
203         *
204         * <blockquote>
205         * <var>m</var> = (<var>P</var><sub>0</sub> + <var>P</var><sub>1</sub>)/2
206         *              + <var>b</var>&times;<b><var>v</var></b>
207         * </blockquote>
208         *
209         * This is leftward if <var>b</var>&nbsp;&gt;&nbsp;0
210         *    and rightward if <var>b</var>&nbsp;&lt;&nbsp;0.
211         *
212         * @param startPoint The {@linkplain Arc#getStartPoint start point}.
213         * @param   endPoint The {@linkplain Arc#getEndPoint end point}.
214         * @param      bulge The distance of the midpoint of the arc from the midpoint of the chord.
215         * @param     normal A direction normal to the chord.
216         *
217         * @throws MismatchedReferenceSystemException If geometric objects given in argument don't
218         *         use compatible {@linkplain CoordinateReferenceSystem coordinate reference system}.
219         * @throws MismatchedDimensionException If geometric objects given in argument don't have
220         *         the expected dimension.
221         */
222        @UML(identifier="GM_Arc(GM_Position[2],Real,Vector)", obligation=MANDATORY, specification=ISO_19107)
223        Arc createArc(Position startPoint, Position endPoint, double bulge, double[] normal)
224                throws MismatchedReferenceSystemException, MismatchedDimensionException;
225    
226        /**
227         * Takes a sequence of {@linkplain Position positions} and constructs a sequence of
228         * 3-point arcs jointing them. By the nature of an arc string, the sequence must have
229         * an odd number of positions.
230         *
231         * @throws MismatchedReferenceSystemException If geometric objects given in argument don't
232         *         use compatible {@linkplain CoordinateReferenceSystem coordinate reference system}.
233         * @throws MismatchedDimensionException If geometric objects given in argument don't have
234         *         the expected dimension.
235         */
236        @UML(identifier="GM_ArcString(GM_Position[3, 5, 7...])", obligation=MANDATORY, specification=ISO_19107)
237        ArcString createArcString(List<Position> points)
238                throws MismatchedReferenceSystemException, MismatchedDimensionException;
239    
240        /**
241         * Equivalents to the {@linkplain #createArc(Position,Position,double,double[]) second
242         * constructor of arc}, except the bulge representation is maintained. The midpoint of
243         * the resulting arc is given by:
244         *
245         * <blockquote><pre>midPoint = ((startPoint + endPoint)/2.0) + bulge&times;normal</pre></blockquote>
246         *
247         * @param startPoint The {@linkplain ArcByBulge#getStartPoint start point}.
248         * @param   endPoint The {@linkplain ArcByBulge#getEndPoint end point}.
249         * @param      bulge The distance of the midpoint of the arc from the midpoint of the chord.
250         * @param     normal A direction normal to the chord.
251         *
252         * @throws MismatchedReferenceSystemException If geometric objects given in argument don't
253         *         use compatible {@linkplain CoordinateReferenceSystem coordinate reference system}.
254         * @throws MismatchedDimensionException If geometric objects given in argument don't have
255         *         the expected dimension.
256         */
257        @UML(identifier="GM_ArcByBulge(GM_Position[2],Real,Vector)", obligation=MANDATORY, specification=ISO_19107)
258        ArcByBulge createArcByBulge(Position startPoint, Position endPoint, double bulge, double[] normal)
259                throws MismatchedReferenceSystemException, MismatchedDimensionException;
260    
261        /**
262         * Equivalent to the {@linkplain #createArc(Position,Position,double,double[]) second
263         * constructor of arc}, except the bulge representation is maintained internal to the
264         * object. The midpoints of the resulting arc is given by:
265         *
266         * <blockquote><code>
267         * midPoint[<var>n</var>] = ((points[<var>n</var>] + points[<var>n</var>+1])/2.0) + (bulge * normal)
268         * </code></blockquote>
269         *
270         * @param  points The points to use as {@linkplain Arc#getStartPoint start} and
271         *                {@linkplain Arc#getEndPoint end points} for each arc. This list size
272         *                must be equals to the {@code bulge} array length plus 1.
273         * @param  bulges The distances of the midpoint of the arc from the midpoint of the chord.
274         * @param normals The directions normal to the chord. This list size must be the same than
275         *                the {@code bulge} array length.
276         *
277         * @throws MismatchedReferenceSystemException If geometric objects given in argument don't
278         *         use compatible {@linkplain CoordinateReferenceSystem coordinate reference system}.
279         * @throws MismatchedDimensionException If geometric objects given in argument don't have
280         *         the expected dimension.
281         */
282        @UML(identifier="GM_ArcStringByBulge(GM_Position[2..n],Real[1..n],Vector[1..n])", obligation=MANDATORY, specification=ISO_19107)
283        ArcStringByBulge createArcStringByBulge(List<Position> points, double[] bulges,
284                                                List<double[]> normals)
285                throws MismatchedReferenceSystemException, MismatchedDimensionException;
286    
287        /**
288         * Constructs a B-spline curve. If the {@code knotSpec} is {@code null}, then the
289         * {@link KnotType} is uniform and the knots are evenly spaced, and except for the
290         * first and last have multiplicity = 1. At the ends the knots are of multiplicity =
291         * {@code degree}+1. If the {@code knotType} is uniform they need not be specified.
292         * <p>
293         * <strong>NOTE:</strong> If the B-spline curve is uniform and degree = 1, the B-spline
294         * is equivalent to a polyline ({@link LineString}). If the {@code knotType} is
295         * {@linkplain KnotType#PIECEWISE_BEZIER piecewise Bezier}, then the knots are
296         * defaulted so that they are evenly spaced, and except for the first and last
297         * have multiplicity equal to degree. At the ends the knots are of multiplicity =
298         * {@code degree}+1.
299         *
300         * @param degree The algebraic degree of the basis functions.
301         * @param points An array of points that are used in the interpolation in this spline curve.
302         * @param knots  The sequence of distinct knots used to define the spline basis functions.
303         * @param knotSpec The type of knot distribution used in defining this spline.
304         *
305         * @throws MismatchedReferenceSystemException If geometric objects given in argument don't
306         *         use compatible {@linkplain CoordinateReferenceSystem coordinate reference system}.
307         * @throws MismatchedDimensionException If geometric objects given in argument don't have
308         *         the expected dimension.
309         */
310        @UML(identifier="GM_BSplineCurve(Integer,GM_PointArray,Sequence<GM_Knot>,GM_KnotType)", obligation=MANDATORY, specification=ISO_19107)
311        BSplineCurve createBSplineCurve(int degree, PointArray points, List<Knot> knots, KnotType knotSpec)
312                throws MismatchedReferenceSystemException, MismatchedDimensionException;
313    
314        /**
315         * Constructs a B-spline surface. If the {@code knotSpec} is not present, then the
316         * {@code knotType} is uniform and the knots are evenly spaced, and, except for the
317         * first and last, have multiplicity = 1. At the ends the knots are of multiplicity
318         * = degree+1. If the {@code knotType} is uniform they need not be specified.
319         *
320         * @param points Arrays of points that are used in the interpolation in this spline surface.
321         * @param degree The algebraic degree of the basis functions for the first and second parameter,
322         *               as an array of length 1 or 2. If only one value is given, then the two degrees
323         *               are equal.
324         * @param knots    The sequence of knots as an array of length 2, or {@code null} if unspecified.
325         * @param knotSpec The type of knot distribution used in defining this spline, or
326         *                 {@code null} if unspecified.
327         *
328         * @throws MismatchedReferenceSystemException If geometric objects given in argument don't
329         *         use compatible {@linkplain CoordinateReferenceSystem coordinate reference system}.
330         * @throws MismatchedDimensionException If geometric objects given in argument don't have
331         *         the expected dimension.
332         */
333        @UML(identifier="GM_BSplineSurface(Sequence<GM_PointArray>,Integer,Sequence<GM_Knot>,GM_KnotType)", obligation=MANDATORY, specification=ISO_19107)
334        BSplineSurface createBSplineSurface(List<PointArray> points, int[] degree, List<Knot>[] knots, KnotType knotSpec)
335                throws MismatchedReferenceSystemException, MismatchedDimensionException;
336    
337        /**
338         * Creates a polygon directly from a set of boundary curves (organized into a
339         * surface boundary) which shall be defined using coplanar {@linkplain Position positions}
340         * as control points.
341         * <p>
342         * <strong>NOTE:</strong> The meaning of exterior in the surface boundary is consistent
343         * with the plane of the constructed planar polygon.
344         *
345         * @param boundary The surface boundary.
346         *
347         * @throws MismatchedReferenceSystemException If geometric objects given in argument don't
348         *         use compatible {@linkplain CoordinateReferenceSystem coordinate reference system}.
349         * @throws MismatchedDimensionException If geometric objects given in argument don't have
350         *         the expected dimension.
351         */
352        @UML(identifier="GM_Polygon(GM_SurfaceBondary)", obligation=MANDATORY, specification=ISO_19107)
353        Polygon createPolygon(SurfaceBoundary boundary)
354                throws MismatchedReferenceSystemException, MismatchedDimensionException;
355    
356        /**
357         * Creates a polygon lying on a spanning surface. There is no restriction of the types of
358         * interpolation used by the composite curves used in the {@linkplain SurfaceBoundary
359         * surface boundary}, but they must all be lie on the
360         * {@linkplain Polygon#getSpanningSurface spanning surface} for the process to succeed.
361         * <p>
362         * <strong>NOTE:</strong> It is important that the boundary components be oriented properly
363         * for this to work. It is often the case that in bounded manifolds, such as the sphere,
364         * there is an ambiguity unless the orientation is properly used.
365         *
366         * @param boundary The surface boundary.
367         * @param spanSurface The spanning surface.
368         *
369         * @throws MismatchedReferenceSystemException If geometric objects given in argument don't
370         *         use compatible {@linkplain CoordinateReferenceSystem coordinate reference system}.
371         * @throws MismatchedDimensionException If geometric objects given in argument don't have
372         *         the expected dimension.
373         */
374        @UML(identifier="GM_Polygon(GM_SurfaceBondary,GM_Surface)", obligation=MANDATORY, specification=ISO_19107)
375        Polygon createPolygon(SurfaceBoundary boundary, Surface spanSurface)
376                throws MismatchedReferenceSystemException, MismatchedDimensionException;
377    
378        /**
379         * Constructs a restricted Delaunay network from triangle corners (posts),
380         * breaklines, stoplines, and maximum length of a triangle side.
381         *
382         * @param  post The corners of the triangles in the TIN.
383         * @param  stopLines lines where the local continuity or regularity of the surface is questionable.
384         * @param  breakLines lines of a critical nature to the shape of the surface.
385         * @param  maxLength Maximal length for retention.
386         *
387         * @throws MismatchedReferenceSystemException If geometric objects given in argument don't
388         *         use compatible {@linkplain CoordinateReferenceSystem coordinate reference system}.
389         * @throws MismatchedDimensionException If geometric objects given in argument don't have
390         *         the expected dimension.
391         */
392        @UML(identifier="GM_Tin(Set<GM_Position>,Set<GM_LineString>,Set<GM_LineString>,Number)", obligation=MANDATORY, specification=ISO_19107)
393        Tin createTin(Set<Position> post, Set<LineString> stopLines,
394                      Set<LineString> breakLines, double maxLength)
395                throws MismatchedReferenceSystemException, MismatchedDimensionException;
396    
397        /**
398         * Constructs polyhedral surface from the facet polygons.
399         *
400         * @param tiles The facet polygons. Must contains at least one polygon.
401         *
402         * @throws MismatchedReferenceSystemException If geometric objects given in argument don't
403         *         use compatible {@linkplain CoordinateReferenceSystem coordinate reference system}.
404         * @throws MismatchedDimensionException If geometric objects given in argument don't have
405         *         the expected dimension.
406         */
407        @UML(identifier="GM_PolyhedralSurace(GM_Polygon)", obligation=MANDATORY, specification=ISO_19107)
408        PolyhedralSurface createPolyhedralSurface(List<Polygon> tiles)
409                throws MismatchedReferenceSystemException, MismatchedDimensionException;
410    
411        /**
412         * Placeholder to create a MultiPrimitive (or derivatives).
413         *
414         * @deprecated <strong>This method is temporary. It will move to some {@code MultiPrimitive}
415         *             factory when the creation of Geometry interfaces will be completed.</strong>
416         *             See <A HREF="http://jira.codehaus.org/browse/GEO-1">GEO-1 on JIRA</A>.
417         */
418        @Deprecated
419        MultiPrimitive createMultiPrimitive();
420    }