/*---------------- FILE HEADER ------------------------------------------ This file is part of deegree. Copyright (C) 2001-2006 by: EXSE, Department of Geography, University of Bonn http://www.giub.uni-bonn.de/deegree/ lat/lon GmbH http://www.lat-lon.de This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Contact: Andreas Poth lat/lon GmbH Aennchenstr. 19 53177 Bonn Germany E-Mail: poth@lat-lon.de Prof. Dr. Klaus Greve Department of Geography University of Bonn Meckenheimer Allee 166 53115 Bonn Germany E-Mail: greve@giub.uni-bonn.de ---------------------------------------------------------------------------*/ package org.deegree.model.spatialschema; import java.util.ArrayList; /** * * * * @version $Revision: 1.6 $ * @author <a href="mailto:poth@lat-lon.de">Andreas Poth</a> * @author last edited by: $Author: poth $ * * @version 1.0. $Revision: 1.6 $, $Date: 2006/08/08 09:17:51 $ * * @since 2.0 */ class LinearContains { /** * the operations returns true if two the submitted points contains */ public static boolean contains( Position point1, Position point2 ) { throw new UnsupportedOperationException( "contains(Position, Position)" + " not supported at the moment." ); } /** * the operations returns true if the submitted point contains * the submitted curve segment */ public static boolean contains( CurveSegment curve, Position point ) { throw new UnsupportedOperationException( "contains(CurveSegment, Position)" + " not supported at the moment." ); } /** * the operation returns true if the submitted point contains * the submitted surface patch */ public static boolean contains( SurfacePatch surface, Position point ) { boolean con = false; Position[] ex = surface.getExteriorRing(); con = contains( ex, point ); if ( con ) { Position[][] inner = surface.getInteriorRings(); if ( inner != null ) { for ( int i = 0; i < inner.length; i++ ) { if ( contains( inner[i], point ) ) { con = false; break; } } } } return con; } /** * the operation returns true if the two submitted curves segments contains */ public static boolean contains( CurveSegment curve1, CurveSegment curve2 ) { throw new UnsupportedOperationException( "contains(CurveSegment, CurveSegment)" + " not supported at the moment." ); } /** * the operation returns true if the submitted curve segment contains * the submitted surface patch */ public static boolean contains( SurfacePatch surface, CurveSegment curve ) { boolean con = true; Position[] ex = surface.getExteriorRing(); Position[] cu = curve.getPositions(); for ( int i = 0; i < cu.length; i++ ) { if ( !contains( ex, cu[i] ) ) { con = false; break; } } if ( con ) { Position[][] inner = surface.getInteriorRings(); if ( inner != null ) { for ( int i = 0; i < inner.length; i++ ) { for ( int j = 0; j < cu.length; j++ ) { if ( contains( inner[i], cu[j] ) ) { con = false; break; } } if ( !con ) { break; } } } } return con; } /** * the operation returns true if the first surface patches contains * the second one */ public static boolean contains( SurfacePatch surface1, SurfacePatch surface2 ) { boolean con = true; Position[] ex = surface1.getExteriorRing(); Position[] ex_ = surface2.getExteriorRing(); for ( int i = 0; i < ex_.length; i++ ) { if ( !contains( ex, ex_[i] ) ) { con = false; break; } } if ( con ) { Position[][] inner = surface1.getInteriorRings(); Position[][] inner_ = surface2.getInteriorRings(); if ( inner != null ) { for ( int i = 0; i < inner.length; i++ ) { // a point of the second exterior is not allowed to be // within a inner ring of the first for ( int j = 0; j < ex_.length; j++ ) { if ( contains( inner[i], ex_[j] ) ) { con = false; break; } } if ( !con ) { break; } // a point of the inner rings of the second is not allowed // to be within a inner ring of the first if ( inner_ != null ) { for ( int k = 0; k < inner_.length; k++ ) { for ( int j = 0; j < inner_[k].length; j++ ) { if ( contains( inner[i], inner_[k][j] ) ) { con = false; break; } } if ( !con ) { break; } } } // a point of the inner rings of the first is not allowed // to be within the second surface for ( int j = 0; j < inner[i].length; j++ ) { if ( contains( surface2, inner[i][j] ) ) { con = false; break; } } if ( !con ) { break; } } } } // surface2 is not allowed to contain one point of surface1 if ( con ) { for ( int i = 0; i < ex.length; i++ ) { if ( contains( surface2, ex[i] ) ) { con = false; break; } } } return con; } /** * the operations returns true if two the submitted points contains */ public static boolean contains( Point point1, Point point2 ) { throw new UnsupportedOperationException( "contains(Point, Point)" + " not supported at the moment." ); } /** * the operations returns true if the submitted point contains * the submitted curve */ public static boolean contains( Curve curve, Point point ) { throw new UnsupportedOperationException( "contains(Curve, Point)" + " not supported at the moment." ); } /** * the operation returns true if the submitted point contains * the submitted surface */ public static boolean contains( Surface surface, Point point ) throws Exception { boolean contain = false; int cnt = surface.getNumberOfSurfacePatches(); for ( int i = 0; i < cnt; i++ ) { if ( contains( surface.getSurfacePatchAt( i ), point.getPosition() ) ) { contain = true; break; } } return contain; } /** * the operation returns true if the two submitted curves contains */ public static boolean contains( Curve curve1, Curve curve2 ) { throw new UnsupportedOperationException( "contains(Curve, Curve)" + " not supported at the moment." ); } /** * Convenience method to extract all <tt>Position</tt>s from a * <tt>Curve</tt>. */ private static Position[] getPositions( Curve curve ) throws GeometryException { ArrayList positions = new ArrayList(1000); for ( int i = 0; i < curve.getNumberOfCurveSegments(); i++ ) { CurveSegment segment = curve.getCurveSegmentAt( i ); Position[] segmentPos = segment.getPositions(); for ( int j = 0; j < segmentPos.length; j++ ) positions.add( segmentPos[j] ); } return (Position[])positions.toArray(); } /** * the operation returns true if the submitted curve contains * the submitted surface */ public static boolean contains( Surface surface, Curve curve ) throws GeometryException { // gather the positions of the crings (exterior and interior) and // the curve as arrays of Positions SurfaceBoundary boundary = (SurfaceBoundary)surface.getBoundary(); Ring extRing = boundary.getExteriorRing(); Ring[] intRings = boundary.getInteriorRings(); Position[] curvePos = getPositions( curve ); Position[] extRingPos = extRing.getPositions(); Position[][] intRingsPos = new Position[intRings.length][]; for ( int i = 0; i < intRings.length; i++ ) intRingsPos[i] = intRings[i].getPositions(); // necessary condition: all points of the curve have to be inside // of the surface's exterior ring and none must be inside of one // of the interior rings for ( int i = 0; i < curvePos.length; i++ ) { if ( !contains( extRingPos, curvePos[i] ) ) { return false; } for ( int j = 0; j < intRings.length; j++ ) { if ( contains( intRingsPos[j], curvePos[i] ) ) { return false; } } } return true; } /** * the operation returns true if the two submitted surfaces contains */ public static boolean contains( Surface surface2, Surface surface1 ) throws Exception { return contains( surface2.getSurfacePatchAt( 0 ), surface1.getSurfacePatchAt( 0 ) ); } /** * the operation returns true if polygon defined by an array of Position * contains the submitted point. */ protected static boolean contains( Position[] positions, Position point ) { if ( positions.length <= 2 ) { return false; } int hits = 0; double lastx = positions[positions.length - 1].getX(); double lasty = positions[positions.length - 1].getY(); double curx; double cury; // Walk the edges of the polygon for ( int i = 0; i < positions.length; lastx = curx, lasty = cury, i++ ) { curx = positions[i].getX(); cury = positions[i].getY(); if ( cury == lasty ) { continue; } double leftx; if ( curx < lastx ) { if ( point.getX() >= lastx ) { continue; } leftx = curx; } else { if ( point.getX() >= curx ) { continue; } leftx = lastx; } double test1; double test2; if ( cury < lasty ) { if ( ( point.getY() < cury ) || ( point.getY() >= lasty ) ) { continue; } if ( point.getX() < leftx ) { hits++; continue; } test1 = point.getX() - curx; test2 = point.getY() - cury; } else { if ( ( point.getY() < lasty ) || ( point.getY() >= cury ) ) { continue; } if ( point.getX() < leftx ) { hits++; continue; } test1 = point.getX() - lastx; test2 = point.getY() - lasty; } if ( test1 < ( test2 / ( lasty - cury ) * ( lastx - curx ) ) ) { hits++; } } return ( ( hits & 1 ) != 0 ); } }/* ******************************************************************** Changes to this class. What the people have been up to: $Log: LinearContains.java,v $ Revision 1.6 2006/08/08 09:17:51 poth NoSuchMethodException substituted by UnsupportedOperation exception Revision 1.5 2006/07/12 14:46:15 poth comment footer added ********************************************************************** */