001    /*----------------    FILE HEADER  ------------------------------------------
002    
003     This file is part of deegree.
004     Copyright (C) 2001-2006 by:
005     EXSE, Department of Geography, University of Bonn
006     http://www.giub.uni-bonn.de/deegree/
007     lat/lon GmbH
008     http://www.lat-lon.de
009    
010     This library is free software; you can redistribute it and/or
011     modify it under the terms of the GNU Lesser General Public
012     License as published by the Free Software Foundation; either
013     version 2.1 of the License, or (at your option) any later version.
014    
015     This library is distributed in the hope that it will be useful,
016     but WITHOUT ANY WARRANTY; without even the implied warranty of
017     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
018     Lesser General Public License for more details.
019    
020     You should have received a copy of the GNU Lesser General Public
021     License along with this library; if not, write to the Free Software
022     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
023    
024     Contact:
025    
026     Andreas Poth
027     lat/lon GmbH
028     Aennchenstr. 19
029     53177 Bonn
030     Germany
031     E-Mail: poth@lat-lon.de
032    
033     Prof. Dr. Klaus Greve
034     Department of Geography
035     University of Bonn
036     Meckenheimer Allee 166
037     53115 Bonn
038     Germany
039     E-Mail: greve@giub.uni-bonn.de
040    
041     
042     ---------------------------------------------------------------------------*/
043    
044    package org.deegree.ogcwebservices.wpvs.operation;
045    
046    import java.awt.geom.Point2D;
047    
048    import javax.media.j3d.PickConeSegment;
049    import javax.vecmath.Point3d;
050    import javax.vecmath.Vector3d;
051    
052    import org.deegree.model.spatialschema.GeometryException;
053    import org.deegree.model.spatialschema.GeometryFactory;
054    import org.deegree.model.spatialschema.Position;
055    import org.deegree.model.spatialschema.SurfaceInterpolation;
056    import org.deegree.model.spatialschema.SurfaceInterpolationImpl;
057    import org.deegree.ogcwebservices.wpvs.j3d.ViewPoint;
058    
059    /**
060     * This class represents the geometry needed for a request cone.
061     * 
062     * @version $Revision: $
063     * @author <a href="mailto:cordes@lat-lon.de">Lyn Buesching</a>
064     * @author last edited by: $Author: $
065     *
066     * @version 1.0. $Revision: $, $Date: $
067     *
068     */
069    public class ConeRequest extends RequestGeometry {
070        
071        // end point of the view ray
072        private Point3d endPointLine;
073        
074        /**
075         * Initializes the two Geometrys for the request with a cone.
076         * 
077         * @param request
078         * @throws GeometryException
079         */
080            public ConeRequest(Get3DFeatureInfo request) {
081                    super( request );
082            endPointLine = new Point3d (calcEndPoint( new ViewPoint( request.getGetViewRequestCopy() ),
083                          (int)request.getDepth(), 
084                          (int)request.getGetViewRequestCopy().getImageDimension().getWidth(),
085                          (int)request.getGetViewRequestCopy().getImageDimension().getHeight(),
086                          request.getClickPoint().x, request.getClickPoint().y ) );
087            }
088    
089            @Override
090            public void setPickshape() {
091                    pickshape = new PickConeSegment( getBeginPointLine(), endPointLine, getRequest().getApexAngle() );
092            }
093    
094            @Override
095            public void setWfsReqGeom() throws GeometryException {
096            
097            Position[] pos = new Position[4];
098            int i = 0;
099            pos[i++] = GeometryFactory.createPosition(getBeginPointLine().x, getBeginPointLine().y, 0);
100            
101            Vector3d tmp = new Vector3d();
102            tmp.sub(getBeginPointLine(), endPointLine);
103            double length = tmp.length();
104            double r = Math.tan( getRequest().getApexAngle() ) * length;
105            
106            double dX = endPointLine.x - getBeginPointLine().x;
107            double dY = endPointLine.y - getBeginPointLine().y;
108            double lengthGround = Math.sqrt(Math.pow( dX, 2 ) + Math.pow( dY, 2 ));
109            
110            double dif = Math.tan( getRequest().getApexAngle() ) * (lengthGround + r);
111            double rot = Math.toRadians(90);
112            if ( dY == 0 && dX > 0 ) {
113                rot = Math.toRadians(270);
114            }else if ( dX != dY ) {
115                rot = Math.atan( dX / dY );
116            }
117            if ( dY < 0 ) {
118                rot = ( rot + Math.toRadians(180) );
119            } else {
120                rot = ( rot + Math.toRadians(360) );
121            }
122            rot = Math.toRadians( 360 ) - (rot  % Math.toRadians( 360 ));
123            
124            // transformation
125            Point2D.Double point2 = trans2d(getBeginPointLine().x, getBeginPointLine().y, 
126                                            rot, new Point2D.Double( dif, lengthGround ));
127            pos[i++] = GeometryFactory.createPosition( point2.x, point2.y, 0 );
128            
129            Point2D.Double point3 = trans2d(getBeginPointLine().x, getBeginPointLine().y, 
130                                            rot , new Point2D.Double( -dif, lengthGround ));
131            pos[i++] = GeometryFactory.createPosition(point3.x, point3.y, 0);
132            
133            pos[i++] = pos[0];
134    
135            SurfaceInterpolation si = new SurfaceInterpolationImpl( 0 );
136            wfsReqGeom = GeometryFactory.createSurface( pos, new Position[0][0], si, getCrs() );
137            }
138            
139            /**
140             * 3-parameter transformation
141             * 
142             * @param translationX the translation in x
143             * @param translationY the translation in x
144             * @param rotation rotation of the transformation
145             * @param transPoint point to transform
146             * 
147             * @return the point in the new coordinatsystem
148             */
149            private Point2D.Double trans2d(double translationX, double translationY, double rotation, 
150                                       Point2D.Double transPoint) {
151    
152            double xTrans = transPoint.x * Math.cos( rotation ) - transPoint.y * Math.sin( rotation ) + translationX;
153                    double yTrans = transPoint.x * Math.sin( rotation ) + transPoint.y * Math.cos( rotation ) + translationY;
154                    return new Point2D.Double( xTrans, yTrans );
155            }
156    }