001 //$HeadURL: svn+ssh://rbezema@svn.wald.intevation.org/deegree/base/tags/2.1/src/org/deegree/model/spatialschema/SurfaceBoundaryImpl.java $
002 /*---------------- FILE HEADER ------------------------------------------
003
004 This file is part of deegree.
005 Copyright (C) 2001-2006 by:
006 EXSE, Department of Geography, University of Bonn
007 http://www.giub.uni-bonn.de/deegree/
008 lat/lon GmbH
009 http://www.lat-lon.de
010
011 This library is free software; you can redistribute it and/or
012 modify it under the terms of the GNU Lesser General Public
013 License as published by the Free Software Foundation; either
014 version 2.1 of the License, or (at your option) any later version.
015
016 This library is distributed in the hope that it will be useful,
017 but WITHOUT ANY WARRANTY; without even the implied warranty of
018 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
019 Lesser General Public License for more details.
020
021 You should have received a copy of the GNU Lesser General Public
022 License along with this library; if not, write to the Free Software
023 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
024
025 Contact:
026
027 Andreas Poth
028 lat/lon GmbH
029 Aennchenstr. 19
030 53115 Bonn
031 Germany
032 E-Mail: poth@lat-lon.de
033
034 Prof. Dr. Klaus Greve
035 Department of Geography
036 University of Bonn
037 Meckenheimer Allee 166
038 53115 Bonn
039 Germany
040 E-Mail: greve@giub.uni-bonn.de
041
042
043 ---------------------------------------------------------------------------*/
044 package org.deegree.model.spatialschema;
045
046 import java.io.Serializable;
047 import java.util.Arrays;
048
049 import org.deegree.framework.log.ILogger;
050 import org.deegree.framework.log.LoggerFactory;
051
052 /**
053 * default implementation of the SurfaceBoundary interface.
054 *
055 * ------------------------------------------------------------
056 * @version 11.6.2001
057 * @author Andreas Poth href="mailto:poth@lat-lon.de"
058 */
059
060 class SurfaceBoundaryImpl extends PrimitiveBoundaryImpl implements SurfaceBoundary,
061 Serializable {
062 /** Use serialVersionUID for interoperability. */
063 private final static long serialVersionUID = 1399131144729310956L;
064
065 private static final ILogger LOG = LoggerFactory.getLogger( SurfaceBoundaryImpl.class );
066
067 public Ring exterior = null;
068 public Ring[] interior = null;
069
070 /**
071 * constructor
072 */
073 public SurfaceBoundaryImpl( Ring exterior, Ring[] interior ) {
074 super( exterior.getCoordinateSystem() );
075 this.exterior = exterior;
076 this.interior = interior;
077 setValid( false );
078 }
079
080 /**
081 * gets the exterior ring
082 */
083 public Ring getExteriorRing() {
084 return exterior;
085 }
086
087 /**
088 * gets the interior ring(s)
089 */
090 public Ring[] getInteriorRings() {
091 return interior;
092 }
093
094 /**
095 * returns the boundary of the boundary
096 */
097 public Boundary getBoundary() {
098 return null;
099 }
100
101 /**
102 * checks if this curve is completly equal to the submitted geometry
103 * @param other object to compare to
104 */
105 public boolean equals( Object other ) {
106 if ( !super.equals( other ) || !( other instanceof SurfaceBoundaryImpl ) ) {
107 return false;
108 }
109
110 if ( !exterior.equals( ( (SurfaceBoundary)other ).getExteriorRing() ) ) {
111 return false;
112 }
113
114 if ( interior != null ) {
115 Ring[] r1 = getInteriorRings();
116 Ring[] r2 = ( (SurfaceBoundary)other ).getInteriorRings();
117
118 if ( !Arrays.equals( r1, r2 ) ) {
119 return false;
120 }
121 } else {
122 if ( ( (SurfaceBoundary)other ).getInteriorRings() != null ) {
123 return false;
124 }
125 }
126
127 return true;
128 }
129
130 /**
131 * The operation "dimension" shall return the inherent dimension of this
132 * Geometry, which shall be less than or equal to the coordinate dimension.
133 * The dimension of a collection of geometric objects shall be the largest
134 * dimension of any of its pieces. Points are 0-dimensional, curves are
135 * 1-dimensional, surfaces are 2-dimensional, and solids are 3-dimensional.
136 */
137 public int getDimension() {
138 return 1;
139 }
140
141 /**
142 * The operation "coordinateDimension" shall return the dimension of the
143 * coordinates that define this Geometry, which must be the same as the
144 * coordinate dimension of the coordinate reference system for this Geometry.
145 */
146 public int getCoordinateDimension() {
147 return exterior.getPositions()[0].getCoordinateDimension();
148 }
149
150 /**
151 * returns a copy of the geometry
152 */
153 public Object clone() {
154 SurfaceBoundary sb = null;
155
156 try {
157 Ring ext = (Ring)( (RingImpl)getExteriorRing() ).clone();
158 Ring[] inn = new Ring[interior.length];
159
160 for ( int i = 0; i < inn.length; i++ ) {
161 inn[i] = (Ring)( (RingImpl)interior[i] ).clone();
162 }
163
164 sb = new SurfaceBoundaryImpl( ext, inn );
165 } catch ( Exception ex ) {
166 LOG.logError( "SurfaceBoundary_Impl.clone: ", ex );
167 }
168
169 return sb;
170 }
171
172 /**
173 * The Boolean valued operation "intersects" shall return TRUE if this Geometry
174 * intersects another Geometry. Within a Complex, the Primitives do not
175 * intersect one another. In general, topologically structured data uses shared
176 * geometric objects to capture intersection information.
177 */
178 public boolean intersects( Geometry gmo ) {
179 boolean inter = exterior.intersects( gmo );
180
181 if ( !inter ) {
182 if ( interior != null ) {
183 for ( int i = 0; i < interior.length; i++ ) {
184 if ( interior[i].intersects( gmo ) ) {
185 inter = true;
186 break;
187 }
188 }
189 }
190 }
191
192 return inter;
193 }
194
195 /**
196 * The Boolean valued operation "contains" shall return TRUE if this Geometry
197 * contains another Geometry.<p></p>
198 * At the moment the operation just works with point geometries
199 */
200 public boolean contains( Geometry gmo ) {
201 boolean con = false;
202
203 con = exterior.contains( gmo );
204
205 if ( con ) {
206 if ( interior != null ) {
207 for ( int i = 0; i < interior.length; i++ ) {
208 if ( interior[i].intersects( gmo ) ) {
209 con = false;
210 break;
211 }
212 }
213 }
214 }
215
216 return con;
217 }
218
219 /**
220 * The Boolean valued operation "contains" shall return TRUE if this Geometry
221 * contains a single point given by a coordinate.<p></p>
222 * dummy implementation
223 */
224 public boolean contains( Position position ) {
225 return contains( new PointImpl( position, null ) );
226 }
227
228 /**
229 * calculates the envelope of the surface boundary
230 */
231 private void calculateEnvelope() {
232 envelope = (Envelope)( (EnvelopeImpl)exterior.getEnvelope() ).clone();
233 }
234
235 /**
236 * calculates the centroid of the surface boundary
237 */
238 private void calculateCentroid() {
239 try {
240 double[] cen = exterior.getCentroid().getAsArray().clone();
241 double cnt = exterior.getAsCurveSegment().getNumberOfPoints();
242
243 for ( int i = 0; i < cen.length; i++ ) {
244 cen[i] *= cnt;
245 }
246
247 if ( interior != null ) {
248 for ( int i = 0; i < interior.length; i++ ) {
249 double[] pos = interior[i].getCentroid().getAsArray();
250 cnt += interior[i].getAsCurveSegment().getNumberOfPoints();
251
252 for ( int j = 0; j < pos.length; j++ ) {
253 cen[j] += ( pos[j] * interior[i].getAsCurveSegment().getNumberOfPoints() );
254 }
255 }
256 }
257
258 for ( int j = 0; j < cen.length; j++ ) {
259 cen[j] /= cnt;
260 }
261
262 centroid = new PointImpl( new PositionImpl( cen ), crs );
263 } catch ( Exception ex ) {
264 LOG.logError( "", ex );
265 }
266 }
267
268 /**
269 * calculates the centroid and the envelope of the surface boundary
270 */
271 protected void calculateParam() {
272 calculateEnvelope();
273 calculateCentroid();
274 setValid( true );
275 }
276
277 /**
278 *
279 *
280 * @return
281 */
282 public String toString() {
283 String ret = null;
284 ret = "interior = " + interior + "\n";
285 ret += ( "exterior = " + exterior + "\n" );
286 return ret;
287 }
288 } /* ********************************************************************
289 Changes to this class. What the people have been up to:
290 $Log$
291 Revision 1.11 2006/07/12 14:46:15 poth
292 comment footer added
293
294 ********************************************************************** */