/*$************************************************************************************************ ** ** $Id$ ** ** $Source: /cvs/ctree/LiteGO1/src/jar/com/polexis/lite/spatialschema/geometry/complex/ComplexImpl.java,v $ ** ** Copyright (C) 2003 Open GIS Consortium, Inc. All Rights Reserved. http://www.opengis.org/Legal/ ** *************************************************************************************************/ package org.geotools.geometry.jts.spatialschema.geometry.complex; // J2SE direct dependencies import org.geotools.geometry.jts.spatialschema.geometry.GeometryImpl; import org.geotools.geometry.jts.JTSGeometry; import org.geotools.geometry.jts.JTSUtils; import com.vividsolutions.jts.geom.Geometry; import java.util.ArrayList; import java.util.Collection; import java.util.HashSet; import java.util.Iterator; import java.util.List; import java.util.Set; import org.opengis.referencing.crs.CoordinateReferenceSystem; import org.opengis.geometry.complex.Complex; /** * A collection of geometrically disjoint, simple {@linkplain Primitive primitives}. If a * {@linkplain Primitive primitive} (other than a {@linkplain org.opengis.geometry.primitive.Point point} * is in a particular {@code Complex}, then there exists a set of primitives of lower dimension * in the same complex that form the boundary of this primitive. * <br><br> * A geometric complex can be thought of as a set in two distinct ways. First, it is a finite set * of objects (via delegation to its elements member) and, second, it is an infinite set of point * values as a subtype of geometric object. The dual use of delegation and subtyping is to * disambiguate the two types of set interface. To determine if a {@linkplain Primitive primitive} * <var>P</var> is an element of a {@code Complex} <var>C</var>, * call: {@code C.element().contains(P)}. * <br><br> * The "{@linkplain #getElements elements}" attribute allows {@code Complex} to inherit the * behavior of {@link Set Set<Primitive>} without confusing the same sort of behavior * inherited from {@link org.opengis.geometry.coordinate.TransfiniteSet TransfiniteSet<DirectPosition>} * inherited through {@link Geometry}. Complexes shall be used in application schemas where * the sharing of geometry is important, such as in the use of computational topology. In a * complex, primitives may be aggregated many-to-many into composites for use as attributes * of features. * * @UML type GM_Complex * @author ISO/DIS 19107 * @author <A HREF="http://www.opengis.org">OpenGIS® consortium</A> * * @source $URL$ * @version 2.0 * * @revisit Some associations are commented out for now. */ public class ComplexImpl extends GeometryImpl implements Complex { //************************************************************************* // Fields //************************************************************************* private List elements; protected Set setViewOfElements; private Set subComplexes; //************************************************************************* // Constructors //************************************************************************* public ComplexImpl(CoordinateReferenceSystem crs) { super(crs); // Override a couple of methods to make sure that they invalidate our // cached JTS representation. elements = new ArrayList() { public boolean add(Object o) { invalidateCachedJTSPeer(); return super.add(o); } public boolean remove(Object o) { invalidateCachedJTSPeer(); return super.remove(o); } }; setViewOfElements = listAsSet(elements); subComplexes = new HashSet(); } protected List getElementList() { return elements; } //************************************************************************* // implement the Complex interface //************************************************************************* /** * This implementation does not support knowing about "larger" objects that * contain this one. Therefore it cannot be known if a complex is maximal. * So this method always returns false. */ public final boolean isMaximal() { return false; } /** * This implementation does not support knowing about "larger" objects that * contain this one. Therefore this method always returns null. */ public final Complex[] getSuperComplexes() { return null; } /** * Returns an array that lists the subcomplexes currently added to this * object. */ public final Complex[] getSubComplexes() { Complex [] result = new Complex[subComplexes.size()]; subComplexes.toArray(result); return result; } /** * Returns a modifiable set that allows the user to add to the list of * subcomplexes. */ public final Set getSubComplexSet() { return subComplexes; } /** * Returns a modifiable reference to our set of elements. This class makes * no attempt to keep the set of subComplexes up to date when this set is * modified, so modify with caution. */ public final Collection/*<Primitive>*/ getElements() { return setViewOfElements; } /** * Creates the JTS peer. */ protected final Geometry computeJTSPeer() { ArrayList subParts = new ArrayList(); Iterator elemIt = elements.iterator(); while (elemIt.hasNext()) { JTSGeometry prim = (JTSGeometry) elemIt.next(); subParts.add(prim.getJTSGeometry()); } // JTS's geometry factory interface has a convenient method that'll // combine geometries by putting them into the most specific collection // class it can. return JTSUtils.GEOMETRY_FACTORY.buildGeometry(subParts); } }