001 //$HeadURL: svn+ssh://jwilden@svn.wald.intevation.org/deegree/base/branches/2.5_testing/src/org/deegree/model/spatialschema/PolygonImpl.java $
002 /*----------------------------------------------------------------------------
003 This file is part of deegree, http://deegree.org/
004 Copyright (C) 2001-2009 by:
005 Department of Geography, University of Bonn
006 and
007 lat/lon GmbH
008
009 This library is free software; you can redistribute it and/or modify it under
010 the terms of the GNU Lesser General Public License as published by the Free
011 Software Foundation; either version 2.1 of the License, or (at your option)
012 any later version.
013 This library is distributed in the hope that it will be useful, but WITHOUT
014 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
015 FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
016 details.
017 You should have received a copy of the GNU Lesser General Public License
018 along with this library; if not, write to the Free Software Foundation, Inc.,
019 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
020
021 Contact information:
022
023 lat/lon GmbH
024 Aennchenstr. 19, 53177 Bonn
025 Germany
026 http://lat-lon.de/
027
028 Department of Geography, University of Bonn
029 Prof. Dr. Klaus Greve
030 Postfach 1147, 53001 Bonn
031 Germany
032 http://www.geographie.uni-bonn.de/deegree/
033
034 e-mail: info@deegree.org
035 ----------------------------------------------------------------------------*/
036 package org.deegree.model.spatialschema;
037
038 import java.io.Serializable;
039
040 import org.deegree.framework.log.ILogger;
041 import org.deegree.framework.log.LoggerFactory;
042 import org.deegree.model.crs.CoordinateSystem;
043
044 /**
045 *
046 *
047 *
048 * @author <a href="mailto:poth@lat-lon.de">Andreas Poth</a>
049 * @author last edited by: $Author: apoth $
050 *
051 * @version $Revision: 25223 $, $Date: 2010-07-09 09:30:18 +0200 (Fr, 09 Jul 2010) $
052 */
053 public class PolygonImpl extends SurfacePatchImpl implements Polygon, Serializable {
054 /** Use serialVersionUID for interoperability. */
055 private final static long serialVersionUID = -1293845886457211088L;
056
057 private static final ILogger LOG = LoggerFactory.getLogger( PolygonImpl.class );
058
059 private SurfaceBoundary boundary = null;
060
061 /**
062 *
063 * @param exteriorRing
064 * @param interiorRings
065 * @param crs
066 * @throws GeometryException
067 */
068 protected PolygonImpl( Ring exteriorRing, Ring[] interiorRings, CoordinateSystem crs ) throws GeometryException {
069 super( exteriorRing, interiorRings, crs );
070 }
071
072 /**
073 * Creates a new PolygonImpl object.
074 *
075 * @param interpolation
076 * @param exteriorRing
077 * @param interiorRings
078 * @param crs
079 *
080 * @throws GeometryException
081 */
082 protected PolygonImpl( SurfaceInterpolation interpolation, Position[] exteriorRing, Position[][] interiorRings,
083 CoordinateSystem crs ) throws GeometryException {
084 super( interpolation, exteriorRing, interiorRings, crs );
085 // TODO
086 // implementation based on segments
087
088 Ring outer = new RingImpl( exteriorRing, crs );
089 Ring[] inner = null;
090
091 if ( interiorRings != null ) {
092 inner = new Ring[interiorRings.length];
093
094 for ( int i = 0; i < inner.length; i++ ) {
095 inner[i] = new RingImpl( interiorRings[i], crs );
096 }
097 }
098
099 boundary = new SurfaceBoundaryImpl( outer, inner );
100 }
101
102 /**
103 * The operation "boundary" shall return the boundary of this SurfacePatch represented as a collection of Curves
104 * organized as a SurfaceBoundary, consisting of Curve instances along the boundary of the aggregate Surface, and
105 * interior to the Surface where SurfacePatches are adjacent.
106 *
107 * @return the boundary of this SurfacePatch
108 *
109 */
110 public SurfaceBoundary getBoundary() {
111 return boundary;
112 }
113
114 @Override
115 public boolean equals( Object other ) {
116 if ( !super.equals( other ) || !( other instanceof PolygonImpl ) ) {
117 return false;
118 }
119
120 return true;
121 }
122
123 @Override
124 public String toString() {
125 String ret = "SurfacePatch: ";
126 ret = "interpolation = " + interpolation + "\n";
127 ret += "exteriorRing = \n";
128 ret += ( exteriorRing + "\n" );
129 ret += ( "interiorRings = " + interiorRings + "\n" );
130 ret += ( "envelope = " + getEnvelope() + "\n" );
131 return ret;
132 }
133
134 @Override
135 public Object clone() {
136 Polygon p = null;
137
138 try {
139 p = new PolygonImpl( new SurfaceInterpolationImpl( getInterpolation().getValue() ), getExteriorRing(),
140 getInteriorRings(), this.crs );
141 } catch ( Exception e ) {
142 LOG.logError( e.getMessage(), e );
143 }
144
145 return p;
146 }
147
148 /**
149 * The Boolean valued operation "intersects" shall return TRUE if this Geometry intersects another Geometry. Within
150 * a Complex, the Primitives do not intersect one another. In general, topologically structured data uses shared
151 * geometric objects to capture intersection information.
152 */
153 public boolean intersects( Geometry gmo ) {
154 boolean inter = false;
155
156 try {
157 if ( gmo instanceof Point ) {
158 double tolerance = ( (Point) gmo ).getTolerance();
159 inter = LinearIntersects.intersects( ( (Point) gmo ).getPosition(), this, tolerance );
160 } else if ( gmo instanceof Curve ) {
161 inter = LinearIntersects.intersects( (Curve) gmo, new SurfaceImpl( this ) );
162 } else if ( gmo instanceof Surface ) {
163 inter = LinearIntersects.intersects( (Surface) gmo, new SurfaceImpl( this ) );
164 } else if ( gmo instanceof Aggregate ) {
165 inter = intersectsMultiObject( (Aggregate) gmo );
166 }
167 } catch ( Exception e ) {
168 LOG.logError( e.getMessage(), e );
169 }
170
171 return inter;
172 }
173
174 /**
175 * the operations returns true if the submitted multi primitive intersects with the curve segment
176 */
177 private boolean intersectsMultiObject( Aggregate mprim )
178 throws Exception {
179 boolean inter = false;
180
181 int cnt = mprim.getSize();
182
183 for ( int i = 0; i < cnt; i++ ) {
184 if ( intersects( mprim.getObjectAt( i ) ) ) {
185 inter = true;
186 break;
187 }
188 }
189
190 return inter;
191 }
192
193 /**
194 * The Boolean valued operation "contains" shall return TRUE if this Geometry contains another Geometry.
195 * <p>
196 * </p>
197 */
198 public boolean contains( Geometry gmo ) {
199 boolean contain = false;
200
201 try {
202 if ( gmo instanceof Point ) {
203 contain = LinearContains.contains( this, ( (Point) gmo ).getPosition(), gmo.getTolerance() );
204 } else if ( gmo instanceof Curve ) {
205 contain = LinearContains.contains( this, ( (Curve) gmo ).getAsLineString(), gmo.getTolerance() );
206 } else if ( gmo instanceof Surface ) {
207 contain = LinearContains.contains( new SurfaceImpl( this ), (Surface) gmo );
208 } else if ( gmo instanceof Aggregate ) {
209 contain = containsMultiObject( (Aggregate) gmo );
210 }
211 } catch ( Exception e ) {
212 LOG.logError( e.getMessage(), e );
213 }
214
215 return contain;
216 }
217
218 /**
219 *
220 *
221 * @param gmo
222 *
223 * @return true if the polygon contains the given aggregate.
224 */
225 private boolean containsMultiObject( Aggregate gmo ) {
226 try {
227 for ( int i = 0; i < gmo.getSize(); i++ ) {
228 if ( !contains( gmo.getObjectAt( i ) ) ) {
229 return false;
230 }
231 }
232 } catch ( Exception e ) {
233 LOG.logError( e.getMessage(), e );
234 }
235
236 return true;
237 }
238 }