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 }