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