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;
033    
034    import java.util.Set;
035    import org.opengis.referencing.crs.CoordinateReferenceSystem;
036    import org.opengis.referencing.operation.MathTransform;
037    import org.opengis.referencing.operation.TransformException;
038    import org.opengis.geometry.complex.Complex;
039    import org.opengis.annotation.UML;
040    import org.opengis.annotation.Extension;
041    
042    import static org.opengis.annotation.Obligation.*;
043    import static org.opengis.annotation.Specification.*;
044    
045    
046    /**
047     * Root class of the geometric object taxonomy. {@code Geometry} supports interfaces common
048     * to all geographically referenced geometric objects. {@code Geometry} instances are sets
049     * of direct positions in a particular coordinate reference system. A {@code Geometry} can
050     * be regarded as an infinite set of points that satisfies the set operation interfaces for a set
051     * of direct positions, {@link TransfiniteSet TransfiniteSet<DirectPosition>}.
052     *
053     * @departure rename
054     *   Renamed <code>GM_Object</code> as <code>Geometry</code> in order to avoid ambiguity with
055     *   <code>java.lang.Object</code>.
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    @UML(identifier="GM_Object", specification=ISO_19107)
062    public interface Geometry extends TransfiniteSet {
063        /**
064         * Returns the coordinate reference system used in {@linkplain DirectPosition direct position}
065         * coordinates. If {@code null}, then this {@code Geometry} uses the coordinate reference
066         * system from another {@code Geometry} in which it is contained.
067         *
068         * The most common example where the coordinate reference system is {@code null} is the elements
069         * and subcomplexes of a maximal {@linkplain Complex complex}. The {@linkplain Complex complex} can
070         * carry the {@linkplain CoordinateReferenceSystem coordinate reference system} for all
071         * {@linkplain org.opengis.geometry.primitive.Primitive primitive} elements
072         * and for all {@link Complex} subcomplexes.
073         * <p>
074         * This association is only navigable from {@code Geometry} to {@linkplain CoordinateReferenceSystem
075         * coordinate reference system}. This means that the coordinate reference system objects in a data set do
076         * not keep a list of {@code Geometry}s that use them.
077         *
078         * @return The coordinate reference system used in {@linkplain DirectPosition direct position}
079         *         coordinates.
080         *
081         * @see #getCoordinateDimension
082         */
083        @UML(identifier="CRS", obligation=MANDATORY, specification=ISO_19107)
084        CoordinateReferenceSystem getCoordinateReferenceSystem();
085    
086        /**
087         * Returns the precision model used to guide the accuracy of topology operations.
088         * <p>
089         * </p>
090         * @return the precision model used for topological operations.
091         */
092        Precision getPrecision();
093    
094        /**
095         * Returns a region in the coordinate reference system that contains this {@code Geometry}.
096         * The default shall be to return an instance of an appropriate {@code Geometry} subclass
097         * that represents the same spatial set returned from {@link #getEnvelope}. The most common
098         * use of {@code mbRegion} will be to support indexing methods that use extents other
099         * than minimum bounding rectangles (MBR or envelopes). This does not restrict the returned
100         * {@code Geometry} from being a non-vector geometric representation, although those
101         * types are not defined within this specification.
102         *
103         * @return The minimum bounding region.
104         *
105         * @see #getEnvelope
106         * @see #getBoundary
107         */
108        @UML(identifier="mbRegion", obligation=MANDATORY, specification=ISO_19107)
109        Geometry getMbRegion();
110    
111        /**
112         * Returns a point value that is guaranteed to be on this {@code Geometry}. The default
113         * logic may be to use the {@linkplain DirectPosition direct position} of the point returned by
114         * {@link #getCentroid} if that point is on the object. Another use of representative point may
115         * be for the placement of labels in systems based on graphic presentation.
116         *
117         * @return The representative point.
118         *
119         * @see #getCentroid
120         */
121        @UML(identifier="representativePoint", obligation=MANDATORY, specification=ISO_19107)
122        DirectPosition getRepresentativePoint();
123    
124        /**
125         * Returns a finite set of {@code Geometry}s containing all of the direct positions on the
126         * boundary of this {@code Geometry}. These object collections shall have further internal
127         * structure where appropriate. The finite set of {@code Geometry}s returned shall be in
128         * the same coordinate reference system as this {@code Geometry}. If the {@code Geometry}
129         * is in a {@linkplain Complex complex}, then the boundary {@code Geometry}s returned shall be
130         * in the same {@linkplain Complex complex}. If the {@code Geometry} is not in any
131         * {@linkplain Complex complex}, then the boundary {@code Geometry}s returned may have been
132         * constructed in response to the operation. The elements of a boundary shall be smaller in
133         * dimension than the original element.
134         *
135         * @return The sets of positions on the boundary.
136         *
137         * @see #getMbRegion
138         * @see #getClosure
139         * @see #getBuffer
140         * @see #getDistance
141         */
142        @UML(identifier="boundary", obligation=MANDATORY, specification=ISO_19107)
143        Boundary getBoundary();
144    
145        /**
146         * Returns a finite set of {@code Geometry}s containing all of the points on the boundary of
147         * this {@code Geometry} and this object (the union of the object and its boundary). These
148         * object collections shall have further internal structure where appropriate. The finite set
149         * of {@code Geometry}s returned shall be in the same coordinate reference system as this
150         * {@code Geometry}. If the {@code Geometry} is in a {@linkplain Complex complex}, then the boundary
151         * {@code Geometry}s returned shall be in the same {@linkplain Complex complex}. If the
152         * {@code Geometry} is not in any {@linkplain Complex complex}, then the boundary
153         * {@code Geometry}s returned may have been constructed in response to the operation.
154         *
155         * @return The sets of points on the union of this object and its boundary.
156         *
157         * @see #getBoundary
158         */
159        @UML(identifier="closure", obligation=MANDATORY, specification=ISO_19107)
160        Complex getClosure();
161    
162        /**
163         * Returns {@code true} if this {@code Geometry} has no interior point of
164         * self-intersection or selftangency. In mathematical formalisms, this means that
165         * every point in the interior of the object must have a metric neighborhood whose
166         * intersection with the object is isomorphic to an <var>n</var>-sphere, where <var>n</var>
167         * is the dimension of this {@code Geometry}.
168         * <p>
169         * Since most coordinate geometries are represented, either directly or indirectly by functions
170         * from regions in Euclidean space of their topological dimension, the easiest test for
171         * simplicity to require that a function exist that is one-to-one and bicontinuous
172         * (continuous in both directions). Such a function is a topological isomorphism. This test
173         * does not work for "closed" objects (that is, objects for which {@link #isCycle} returns
174         * {@code true}).
175         *
176         * @return {@code true} if this object has no interior point of self-intersection or
177         *         selftangency.
178         *
179         * @see #isCycle
180         */
181        @UML(identifier="isSimple", obligation=MANDATORY, specification=ISO_19107)
182        boolean isSimple();
183    
184        /**
185         * Returns {@code true} if this {@code Geometry} has an empty boundary after topological
186         * simplification (removal of overlaps between components in non-structured aggregates, such as
187         * subclasses of {@link org.opengis.geometry.aggregate.Aggregate}). This condition is alternatively
188         * referred to as being "closed" as in a "closed curve." This creates some confusion since there
189         * are two distinct and incompatible definitions for the word "closed". The use of the word cycle
190         * is rarer (generally restricted to the field of algebraic topology), but leads to less confusion.
191         * Essentially, an object is a cycle if it is isomorphic to a geometric object that is the
192         * boundary of a region in some Euclidean space. Thus a curve is a cycle if it is isomorphic
193         * to a circle (has the same start and end point). A surface is a cycle if it isomorphic to the
194         * surface of a sphere, or some torus. A solid, with finite size, in a space of dimension 3 is
195         * never a cycle.
196         *
197         * @return {@code true} if this {@code Geometry} has an empty boundary after
198         *         topological simplification.
199         *
200         * @see #isSimple
201         */
202        @UML(identifier="isCycle", obligation=MANDATORY, specification=ISO_19107)
203        boolean isCycle();
204    
205        /**
206         * Returns the distance between this {@code Geometry} and another {@code Geometry}.
207         * This distance is defined to be the greatest lower bound of the set of distances between
208         * all pairs of points that include one each from each of the two {@code Geometry}s. A
209         * "distance" value shall be a positive number associated to a distance unit such as meter
210         * or standard foot. If necessary, the second geometric object shall be transformed into
211         * the same coordinate reference system as the first before the distance is calculated.
212         * <p>
213         * If the geometric objects overlap, or touch, then their distance apart shall be zero.
214         * Some current implementations use a "negative" distance for such cases, but the approach
215         * is neither consistent between implementations, nor theoretically viable.
216         * <p>
217         * <strong>NOTE:</strong> The role of the reference system in distance calculations is
218         * important. Generally, there are at least three types of distances that may be defined
219         * between points (and therefore between geometric objects): map distance, geodesic distance,
220         * and terrain distance.
221         * <ul>
222         *   <li>Map distance is the distance between the points as defined by their positions in a
223         *       coordinate projection (such as on a map when scale is taken into account). Map distance
224         *       is usually accurate for small areas where scale functions have well-behaved derivatives.</li>
225         *   <li>Geodesic distance is the length of the shortest curve between those two points along the
226         *       surface of the earth model being used by the coordinate reference system. Geodesic
227         *       distance behaves well for wide areas of coverage, and takes the earth's curvature
228         *       into account. It is especially handy for air and sea navigation, although care should
229         *       be taken to distinguish between rhumb line (curves of constant bearing) and geodesic
230         *       curve distance.</li>
231         *   <li>Terrain distance takes into account the local vertical displacements (hypsography).
232         *       Terrain distance can be based either on a geodesic distance or a map distance.</li>
233         * </ul>
234         *
235         * @param  geometry The other object.
236         * @return The distance between the two objects.
237         * @unitof Distance
238         * @since GeoAPI 2.1
239         *
240         * @see #getBoundary
241         * @see #getBuffer
242         * @see org.opengis.referencing.cs.CoordinateSystem#getAxis
243         */
244        @UML(identifier="distance", obligation=MANDATORY, specification=ISO_19107)
245        double distance(Geometry geometry);
246    
247        /**
248         * Returns the inherent dimension of this {@code Geometry}, which shall be less than or
249         * equal to the {@linkplain #getCoordinateDimension coordinate dimension}. The dimension of
250         * a collection of geometric objects shall be the largest dimension of any of its pieces.
251         * Points are 0-dimensional, curves are 1-dimensional, surfaces are 2-dimensional, and solids
252         * are 3-dimensional. Locally, the dimension of a geometric object at a point is the dimension
253         * of a local neighborhood of the point - that is the dimension of any coordinate neighborhood
254         * of the point. Dimension is unambiguously defined only for {@linkplain DirectPosition direct
255         * positions} interior to this {@code Geometry}. If the passed {@linkplain DirectPosition
256         * direct position} is {@code null}, then the operation shall return the largest possible
257         * dimension for any {@linkplain DirectPosition direct position} in this {@code Geometry}.
258         *
259         * @param point The point where to evaluate the dimension, or {@code null}.
260         * @return The inherent dimension.
261         *
262         * @see #getCoordinateDimension
263         */
264        @UML(identifier="dimension", obligation=MANDATORY, specification=ISO_19107)
265        int getDimension(DirectPosition point);
266    
267        /**
268         * Returns the dimension of the coordinates that define this {@code Geometry}, which must
269         * be the same as the coordinate dimension of the coordinate reference system for this
270         * {@code Geometry}.
271         *
272         * @return The coordinate dimension.
273         *
274         * @see #getDimension
275         * @see #getCoordinateReferenceSystem
276         */
277        @UML(identifier="coordinateDimension", obligation=MANDATORY, specification=ISO_19107)
278        int getCoordinateDimension();
279    
280        /**
281         * Returns the set of maximal complexes within which this {@code Geometry} is contained.
282         * As a set of primitives, a {@linkplain Complex complex} may be contained as a set in another
283         * larger {@linkplain Complex complex}, referred to as a "super complex" of the original.
284         * A {@linkplain Complex complex} is maximal if there is no such larger super complex.
285         *
286         * @return The set of maximal complexes within which this {@code Geometry} is contained.
287         */
288        @UML(identifier="maximalComplex", obligation=MANDATORY, specification=ISO_19107)
289        Set<? extends Complex> getMaximalComplex();
290    
291        /**
292         * Returns a new {@code Geometry} that is the coordinate transformation of this
293         * {@code Geometry} into the passed coordinate reference system within the accuracy
294         * of the transformation.
295         *
296         * @param  newCRS The new coordinate reference system.
297         * @return The transformed {@code Geometry}.
298         * @throws TransformException if the transformation failed.
299         */
300        @UML(identifier="transform", obligation=MANDATORY, specification=ISO_19107)
301        Geometry transform(CoordinateReferenceSystem newCRS) throws TransformException;
302    
303        /**
304         * Returns a new {@code Geometry} that is the coordinate transformation of this
305         * {@code Geometry} into the passed coordinate reference system, using the
306         * specified transform. It is the user responsibility to ensure that the supplied
307         * transform is appropriate for this geometry.
308         *
309         * @param  newCRS The new coordinate reference system.
310         * @param  transform The transform from the existing coordinate reference system
311         *         to the new coordinate reference system.
312         * @throws TransformException if the transformation failed.
313         * @return The transformed {@code Geometry}.
314         */
315        @Extension
316        Geometry transform(CoordinateReferenceSystem newCRS, MathTransform transform) throws TransformException;
317    
318        /**
319         * Returns the minimum bounding box for this {@code Geometry}. This shall be the
320         * coordinate region spanning the minimum and maximum value for each ordinate taken on by
321         * {@linkplain DirectPosition direct positions} in this {@code Geometry}. The simplest
322         * representation for an envelope consists of two {@linkplain DirectPosition direct positions},
323         * the first one containing all the minimums for each ordinate, and second one containing all
324         * the maximums. However, there are cases for which these two positions would be outside the
325         * domain of validity of the object's coordinate reference system.
326         *
327         * @return The envelope.
328         *
329         * @see #getMbRegion
330         */
331        @UML(identifier="envelope", obligation=MANDATORY, specification=ISO_19107)
332        Envelope getEnvelope();
333    
334        /**
335         * Returns the mathematical centroid for this {@code Geometry}. The result is not guaranteed
336         * to be on the object. For heterogeneous collections of primitives, the centroid only takes
337         * into account those of the largest dimension. For example, when calculating the centroid of
338         * surfaces, an average is taken weighted by area. Since curves have no area they do not
339         * contribute to the average.
340         *
341         * @return The centroid.
342         *
343         * @see #getRepresentativePoint
344         */
345        @UML(identifier="centroid", obligation=MANDATORY, specification=ISO_19107)
346        DirectPosition getCentroid();
347    
348        /**
349         * Returns a {@code Geometry} that represents the convex hull of this {@code Geometry}.
350         * Convexity requires the use of "lines" or "curves of shortest length" and the use of different
351         * coordinate systems may result in different versions of the convex hull of an object. Each
352         * implementation shall decide on an appropriate solution to this ambiguity. For two reasonable
353         * coordinate systems, a convex hull of an object in one will be very closely approximated by
354         * the transformed image of the convex hull of the same object in the other.
355         *
356         * @return The convex hull.
357         */
358        @UML(identifier="convexHull", obligation=MANDATORY, specification=ISO_19107)
359        Geometry getConvexHull();
360    
361        /**
362         * Returns a {@code Geometry} containing all points whose distance from this
363         * {@code Geometry} is less than or equal to the distance passed as a parameter.
364         * The {@code Geometry} returned is in the same reference system as this original
365         * {@code Geometry}. The dimension of the returned {@code Geometry} is normally
366         * the same as the coordinate dimension - a collection of
367         * {@linkplain org.opengis.geometry.primitive.Surface surfaces} in 2D space and a collection of
368         * {@linkplain org.opengis.geometry.primitive.Solid solids} in 3D space, but this may be application
369         * defined.
370         *
371         * @param distance The distance.
372         * @return A geometry containing all points whose distance from this {@code Geometry}
373         *         is less than or equal to the specified distance.
374         * @unitof Distance (for the argument)
375         *
376         * @see #getBoundary
377         * @see #getDistance
378         * @see org.opengis.referencing.cs.CoordinateSystem#getAxis
379         */
380        @UML(identifier="buffer", obligation=MANDATORY, specification=ISO_19107)
381        Geometry getBuffer(double distance);
382    
383        /**
384         * Returns {@code false} if this geometry is immutable. Immutable geometries are
385         * guarantee to never change their state, neither directly (through a change in this object)
386         * or indirectly (through a change in an other object this geometry depends upon). Immutable
387         * geometries avoid the need for {@linkplain #clone cloning them}. More specifically:
388         *
389         * <UL>
390         *   <LI><P>If {@code false}, then this geometry is <cite>immutable</cite>. It is
391         *       guarantee that a call to any {@code setFoo(...)} method will throws an
392         *       {@link UnmodifiableGeometryException} (that said, <cite>immutable</cite> geometries
393         *       are necessarily <cite>unmodifiable</cite>. The converse is not true, see next point
394         *       below). This geometry will never change its state, and there is no need for
395         *       {@linkplain #clone cloning it}.</P></LI>
396         *   <LI><P>If {@code true}, then this geometry is <cite>mutable</cite>. Note that
397         *       <cite>mutable</cite> geometry is not synonymous of <cite>modifiable</cite>
398         *       geometry. The nuance lays in whatever the geometry may changes its state
399         *       directly (as of user request) or indirectly:<P></LI>
400         *       <UL>
401         *         <LI><P>This geometry may be <cite>modifiable</cite>, in which case invoking
402         *             {@code setFoo(...)} methods is legal and will not throws exception.</P></LI>
403         *         <LI><P>This geometry may still <cite>unmodifiable</cite>. User is not allowed to
404         *             modify it himself and invoking any {@code setFoo(...)} method will throws
405         *             an {@link UnmodifiableGeometryException}. However, the implementation may change
406         *             the geometry itself (for example a time-varying geometry).</P></LI>
407         *       </UL>
408         *   </LI>
409         * </UL>
410         *
411         * @return {@code true} if this geometry is mutable.
412         */
413        @Extension
414        boolean isMutable();
415    
416        /**
417         * Returns an immutable copy of this geometry.  The returned Geometry is
418         * guaranteed to have an {@code isMutable()} value of false.  Moreover,
419         * as per the contract of {@code isMutable()}, its values will never
420         * change.  Any attempts to change the values of the returned object will
421         * result in a {@code UnmodifiableGeometryException}.
422         * <p>
423         * Implementors are free to return {@code this} if this object is
424         * already immutable.
425         *
426         * @return An immutable copy of this geometry.
427         */
428        @Extension
429        Geometry toImmutable();
430    
431        /**
432         * Returns a clone of this geometry with <em>deep</em> copy semantic. Any change on this object
433         * will have no impact on the returned clone, and conversely. For big geometries, implementations
434         * are encouraged to share as much internal data as possible (as opposed to performing a real
435         * copy of the data), while preserving the deep copy semantic.
436         *
437         * <P>Special cases:</P>
438         *
439         * <UL>
440         *   <LI><P>If this geometry is immutable (<code>{@linkplain #isMutable} == false</code>), then
441         *       there is no need for cloning this object. This method may return {@code this}
442         *       or returns a modifiable copy of this object, at implementation choice.</P></LI>
443         *   <LI><P>If a deep copy semantic is not possible at a reasonable cost (for example for some
444         *       database backend), then this method throws a {@link CloneNotSupportedException}.</P></LI>
445         *   <LI><P>If a deep cloning is possible for all case (i.e. if this method never throws
446         *       {@link CloneNotSupportedException}), then the implementation should implements
447         *       the {@link Cloneable} interface.</P></LI>
448         * </UL>
449         *
450         * @return A clone of this geometry, which may or may not be mutable.
451         * @throws CloneNotSupportedException if this object do not support clone. This exception is
452         *         never throws if this object implements {@link Cloneable}.
453         *
454         * @see Cloneable
455         * @see #isMutable
456         */
457        Geometry clone() throws CloneNotSupportedException;
458    }