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.primitive;
033    
034    import java.util.Set;
035    import org.opengis.geometry.Geometry;
036    import org.opengis.geometry.complex.Complex;
037    import org.opengis.geometry.complex.Composite;
038    import org.opengis.annotation.Association;
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     * Abstract root class of the geometric primitives. Its main purpose is to define the basic
047     * "boundary" operation that ties the primitives in each dimension together. A geometric primitive
048     * is a geometric object that is not decomposed further into other primitives in the system. This
049     * includes curves and surfaces, even though they are composed of curve segments and surface patches,
050     * respectively. Those curve segments and surface patches cannot exist outside the context of a
051     * primitive.
052     * <p>
053     * Any geometric object that is used to describe a feature is a collection of geometric primitives.
054     * A collection of geometric primitives may or may not be a geometric complex. Geometric complexes
055     * have additional properties such as closure by boundary operations and mutually exclusive component
056     * parts. {@code Primitive} and {@link Complex} share most semantics, in the meaning of operations
057     * and attributes. There is an exception in that a {@code Primitive} shall not contain its boundary
058     * (except in the trivial case of {@linkplain Point point} where the boundary is empty), while a
059     * {@linkplain Complex complex} shall contain its boundary in all cases.
060     *
061     * @version <A HREF="http://www.opengeospatial.org/standards/as">ISO 19107</A>
062     * @author Martin Desruisseaux (IRD)
063     * @since GeoAPI 1.0
064     *
065     * @see PrimitiveFactory#createPrimitive(org.opengis.geometry.Envelope)
066     *
067     * @todo Some associations are commented out for now.
068     */
069    @UML(identifier="GM_Primitive", specification=ISO_19107)
070    public interface Primitive extends Geometry {
071        /**
072         * Returns the boundary of a {@code Primitive} as a set of
073         * {@code Primitive}s. This is a specialization of the operation at
074         * {@link Geometry}, which does not restrict the class of the returned collection.
075         * The organization of the boundary set of a {@code Primitive} depends on the
076         * type of the primitive.
077         *
078         * @return The sets of positions on the boundary.
079         */
080        @UML(identifier="boundary", obligation=MANDATORY, specification=ISO_19107)
081        PrimitiveBoundary getBoundary();
082    
083        /**
084         * Returns the {@code Primitive}s which are by definition coincident with this one.
085         * This allows applications to override the
086         * {@link org.opengis.geometry.TransfiniteSet TransfiniteSet&lt;DirectPosition&gt;}
087         * interpretation and its associated computational geometry, and declare one
088         * {@code Primitive} to be "interior to" another.
089         *
090         * This set should normally be empty when the {@code Primitive}s are within a
091         * {@linkplain Complex complex}, since in that case the boundary
092         * information is sufficient for most cases.
093         *
094         * This association should not be used when the two {@code Primitive}s are not close
095         * to one another. The intent is to allow applications to compensate for inherent and
096         * unavoidable round off, truncation, and other mathematical problems indigenous to
097         * computer calculations.
098         *
099         * @return The set of primitives contained into this primitive.
100         *
101         * @todo Using a {@link Set} returns type allows the user to add or remove element in
102         *       this set at his convenience. Is it the right interpretation of this specification?
103         *
104         * @see #getContainingPrimitives
105         */
106        @UML(identifier="containedPrimitive", obligation=MANDATORY, specification=ISO_19107)
107        Set<Primitive> getContainedPrimitives();
108    
109        /**
110         * Returns the {@code Primitive}s which are by definition coincident with this one.
111         *
112         * @return The set of primitives which contains this primitive.
113         *
114         * @todo Using a {@link Set} returns type allows the user to add or remove element in
115         *       this set at his convenience. Is it the right interpretation of this specification?
116         *
117         * @todo Should we stretch out some relation with contained primitive? For example
118         *       should we update the specification with something like the following?
119         *       "Invoking {@code B.getContainingPrimitive().add(A)} is equivalent to
120         *        invoking {@code A.getContainedPrimitive().add(B)}".
121         *
122         * @see #getContainedPrimitives
123         */
124        @UML(identifier="containingPrimitive", obligation=MANDATORY, specification=ISO_19107)
125        Set<Primitive> getContainingPrimitives();
126    
127        /**
128         * Returns the set of complexes which contains this primitive. A {@code Primitive} may
129         * be in several {@linkplain Complex complexes}. This association may not be navigable in this
130         * direction (from primitive to complex), depending on the implementation.
131         *
132         * @return The set of complexes which contains this primitive.
133         */
134        @UML(identifier="complex", obligation=MANDATORY, specification=ISO_19107)
135        Set<Complex> getComplexes();
136    
137        /**
138         * Returns the owner of this primitive. This method is <em>optional</em> since
139         * the association in ISO 19107 is navigable only from {@code Composite} to
140         * {@code Primitive}, not the other way.
141         *
142         * @return The owner of this primitive, or {@code null} if the association is
143         *         not available or not implemented that way.
144         *
145         * @see Composite#getGenerators
146         * @issue http://jira.codehaus.org/browse/GEO-63
147         */
148        @Association("Composition")
149        @UML(identifier="composite", obligation=OPTIONAL, specification=ISO_19107)
150        Composite getComposite();
151    
152        /**
153         * Returns the orientable primitives associated with this primitive. Each {@code Primitive} of
154         * dimension 1 or 2 is associated to two {@linkplain OrientablePrimitive orientable primitives},
155         * one for each possible orientation. For curves and surfaces, there are exactly two orientable
156         * primitives for each geometric object. For the positive orientation, the
157         * {@linkplain OrientablePrimitive orientable primitive} shall be the corresponding
158         * {@linkplain Curve curve} or {@linkplain Surface surface}.
159         * <p>
160         * This method is mandatory for {@linkplain Curve curves} and {@link Surface surfaces},
161         * and is not allowed for {@linkplain Point Points} and {@linkplain Solid solids}. The
162         * later should return {@code null}.
163         *
164         * @return The orientable primitives as an array of length 2, or {@code null} if none.
165         *
166         * @see OrientablePrimitive#getPrimitive
167         * @issue http://jira.codehaus.org/browse/GEO-63
168         */
169        @Association("Oriented")
170        @UML(identifier="proxy", obligation=CONDITIONAL, specification=ISO_19107)
171        OrientablePrimitive[] getProxy();
172    
173    //    public org.opengis.topology.primitive.TP_Primitive topology[];
174    }