001 //$HeadURL: svn+ssh://jwilden@svn.wald.intevation.org/deegree/base/branches/2.5_testing/src/org/deegree/model/spatialschema/SurfaceBoundaryImpl.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 import java.util.Arrays; 040 041 import org.deegree.framework.log.ILogger; 042 import org.deegree.framework.log.LoggerFactory; 043 044 /** 045 * default implementation of the SurfaceBoundary interface. 046 * 047 * ------------------------------------------------------------ 048 * 049 * @version 11.6.2001 050 * @author Andreas Poth href="mailto:poth@lat-lon.de" 051 */ 052 053 public class SurfaceBoundaryImpl extends PrimitiveBoundaryImpl implements SurfaceBoundary, Serializable { 054 /** Use serialVersionUID for interoperability. */ 055 private final static long serialVersionUID = 1399131144729310956L; 056 057 private static final ILogger LOG = LoggerFactory.getLogger( SurfaceBoundaryImpl.class ); 058 059 /** 060 * The exterior ring of the surface boundary 061 */ 062 public Ring exterior = null; 063 064 /** 065 * The interior ring of the surface boundary 066 */ 067 public Ring[] interior = null; 068 069 /** 070 * @param exterior 071 * @param interior 072 */ 073 protected SurfaceBoundaryImpl( Ring exterior, Ring[] interior ) { 074 super( exterior.getCoordinateSystem() ); 075 this.exterior = exterior; 076 this.interior = interior; 077 setValid( false ); 078 } 079 080 public Ring getExteriorRing() { 081 return exterior; 082 } 083 084 public Ring[] getInteriorRings() { 085 return interior; 086 } 087 088 /** 089 * @return the boundary of the boundary 090 */ 091 @Override 092 public Boundary getBoundary() { 093 return null; 094 } 095 096 @Override 097 public boolean equals( Object other ) { 098 if ( !super.equals( other ) || !( other instanceof SurfaceBoundaryImpl ) ) { 099 return false; 100 } 101 102 if ( !exterior.equals( ( (SurfaceBoundary) other ).getExteriorRing() ) ) { 103 return false; 104 } 105 106 if ( interior != null ) { 107 Ring[] r1 = getInteriorRings(); 108 Ring[] r2 = ( (SurfaceBoundary) other ).getInteriorRings(); 109 110 if ( !Arrays.equals( r1, r2 ) ) { 111 return false; 112 } 113 } else { 114 if ( ( (SurfaceBoundary) other ).getInteriorRings() != null ) { 115 return false; 116 } 117 } 118 119 return true; 120 } 121 122 /** 123 * The operation "dimension" shall return the inherent dimension of this Geometry, which shall be less than or equal 124 * to the coordinate dimension. The dimension of a collection of geometric objects shall be the largest dimension of 125 * any of its pieces. Points are 0-dimensional, curves are 1-dimensional, surfaces are 2-dimensional, and solids are 126 * 3-dimensional. 127 */ 128 public int getDimension() { 129 return 1; 130 } 131 132 /** 133 * The operation "coordinateDimension" shall return the dimension of the coordinates that define this Geometry, 134 * which must be the same as the coordinate dimension of the coordinate reference system for this Geometry. 135 */ 136 public int getCoordinateDimension() { 137 return exterior.getPositions()[0].getCoordinateDimension(); 138 } 139 140 @Override 141 public Object clone() { 142 SurfaceBoundary sb = null; 143 144 try { 145 Ring ext = (Ring) ( (RingImpl) getExteriorRing() ).clone(); 146 Ring[] inn = new Ring[interior.length]; 147 148 for ( int i = 0; i < inn.length; i++ ) { 149 inn[i] = (Ring) ( (RingImpl) interior[i] ).clone(); 150 } 151 152 sb = new SurfaceBoundaryImpl( ext, inn ); 153 } catch ( Exception ex ) { 154 LOG.logError( "SurfaceBoundary_Impl.clone: ", ex ); 155 } 156 157 return sb; 158 } 159 160 @Override 161 public boolean intersects( Geometry gmo ) { 162 boolean inter = exterior.intersects( gmo ); 163 164 if ( !inter ) { 165 if ( interior != null ) { 166 for ( int i = 0; i < interior.length; i++ ) { 167 if ( interior[i].intersects( gmo ) ) { 168 inter = true; 169 break; 170 } 171 } 172 } 173 } 174 175 return inter; 176 } 177 178 @Override 179 public boolean contains( Geometry gmo ) { 180 boolean con = false; 181 182 con = exterior.contains( gmo ); 183 184 if ( con ) { 185 if ( interior != null ) { 186 for ( int i = 0; i < interior.length; i++ ) { 187 Position[] pos = interior[i].getPositions(); 188 for ( int j = 0; j < pos.length / 2; j++ ) { 189 Position p = pos[j]; 190 pos[j] = pos[pos.length - j - 1]; 191 pos[pos.length - j - 1] = p; 192 } 193 Ring ring = null; 194 try { 195 ring = new RingImpl( pos, getCoordinateSystem() ); 196 } catch ( GeometryException e ) { 197 e.printStackTrace(); 198 } 199 if ( ring.intersects( gmo ) || ring.contains( gmo ) ) { 200 con = false; 201 break; 202 } 203 } 204 } 205 } 206 207 return con; 208 } 209 210 /** 211 * The Boolean valued operation "contains" shall return TRUE if this Geometry contains a single point given by a 212 * coordinate. 213 * <p> 214 * </p> 215 * dummy implementation 216 */ 217 @Override 218 public boolean contains( Position position ) { 219 return contains( new PointImpl( position, null ) ); 220 } 221 222 /** 223 * calculates the envelope of the surface boundary 224 */ 225 private void calculateEnvelope() { 226 envelope = (Envelope) ( (EnvelopeImpl) exterior.getEnvelope() ).clone(); 227 } 228 229 /** 230 * calculates the centroid of the surface boundary 231 */ 232 private void calculateCentroid() { 233 try { 234 double[] cen = exterior.getCentroid().getAsArray().clone(); 235 double cnt = exterior.getAsCurveSegment().getNumberOfPoints(); 236 237 for ( int i = 0; i < cen.length; i++ ) { 238 cen[i] *= cnt; 239 } 240 241 if ( interior != null ) { 242 for ( int i = 0; i < interior.length; i++ ) { 243 double[] pos = interior[i].getCentroid().getAsArray(); 244 cnt += interior[i].getAsCurveSegment().getNumberOfPoints(); 245 246 for ( int j = 0; j < pos.length; j++ ) { 247 cen[j] += ( pos[j] * interior[i].getAsCurveSegment().getNumberOfPoints() ); 248 } 249 } 250 } 251 252 for ( int j = 0; j < cen.length; j++ ) { 253 cen[j] /= cnt; 254 } 255 256 centroid = new PointImpl( new PositionImpl( cen ), crs ); 257 } catch ( Exception ex ) { 258 LOG.logError( "", ex ); 259 } 260 } 261 262 @Override 263 protected void calculateParam() { 264 calculateEnvelope(); 265 calculateCentroid(); 266 setValid( true ); 267 } 268 269 @Override 270 public String toString() { 271 String ret = null; 272 ret = "interior = " + interior + "\n"; 273 ret += ( "exterior = " + exterior + "\n" ); 274 return ret; 275 } 276 }