001    /*----------------    FILE HEADER  ------------------------------------------
002    
003     This file is part of deegree.
004     Copyright (C) 2001-2008 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 javax.media.j3d.PickShape;
047    import javax.media.j3d.Transform3D;
048    import javax.vecmath.AxisAngle4d;
049    import javax.vecmath.Point3d;
050    import javax.vecmath.Vector3d;
051    
052    import org.deegree.model.crs.CoordinateSystem;
053    import org.deegree.model.spatialschema.Geometry;
054    import org.deegree.model.spatialschema.GeometryException;
055    import org.deegree.ogcwebservices.wpvs.j3d.ViewPoint;
056    
057    /**
058     * This abstract class represents a geometry needed for Get3DFeatureInfoRequest. 
059     * It contains the 3d geometry and its 2d projektion. The 2d geometry is required
060     * for WFS request, the 3d geometry for the final test of intersection.  
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 abstract class RequestGeometry {
070            
071            protected Get3DFeatureInfo request;
072        
073            // begin point of the view ray
074        private Point3d beginPointLine;
075        
076            private CoordinateSystem crs;
077            
078            // geometry for wfs query 
079        protected Geometry wfsReqGeom;
080            
081            // 3d geometry: needed for final testing   
082        protected PickShape pickshape;
083            
084            /**
085             * Constructor to initialize the attributes needed for all geometries
086             * 
087             * @param request the Get3DFeatureInfoRequest 
088             */
089            public RequestGeometry ( Get3DFeatureInfo request ) {
090                    this.request = request;
091            crs = request.getGetViewRequestCopy().getCrs();
092            beginPointLine = new ViewPoint(request.getGetViewRequestCopy()).getObserverPosition();
093            }
094        
095            
096            // GETTERS
097            public PickShape getPickshape() {
098                    return pickshape;
099            }
100    
101            public Geometry getWfsReqGeom() {
102                    return wfsReqGeom;
103            }
104            
105            public Point3d getBeginPointLine() {
106                    return beginPointLine;
107            }
108    
109            public CoordinateSystem getCrs() {
110                    return crs;
111            }
112    
113            public Get3DFeatureInfo getRequest() {
114                    return request;
115            }
116            
117            // abstract methods
118            /**
119             * sets the geometry needed for WFS request 
120             */
121            public abstract void setWfsReqGeom() throws GeometryException;
122            /**
123             * sets the geometry needed for final test of intersection 
124             */
125            public abstract void setPickshape();
126            
127        /**
128         * Calculates a ray thro the ViewPoint and the ClickPoint.
129         * 
130         * @param clickI 
131         * @param clickJ 
132         * @return
133             */
134            protected Point3d calcEndPoint( ViewPoint viewPoint, double depth, int width, int height, int clickI, int clickJ ) {
135            // sets extension of the ray 
136            double extension = viewPoint.getFarClippingPlane();
137            if ( depth > 0 && depth < extension ) {
138                extension = depth;
139            }
140             GetView getView = request.getGetViewRequestCopy();
141            
142            // rotates the cklickpoint to the roll-angle
143            double roll = getView.getRoll();
144            double deltaI = -( width / 2 ) + clickI;
145            double deltaJ = ( height / 2 ) - clickJ;
146            
147            double x =   deltaI * Math.cos( roll ) + deltaJ * Math.sin( roll );
148            double y = - deltaI * Math.sin( roll ) + deltaJ * Math.cos( roll );
149    
150            // calculates the angles to rotate the vector (vp-poi)
151            double aov = viewPoint.getAngleOfView();
152            double distProj = ( width / 2 ) / Math.tan( aov / 2 );
153            
154            double angleI = Math.atan( x / distProj );      
155            double angleJ = Math.atan( y / distProj );
156    
157            Point3d vp  = viewPoint.getObserverPosition();
158            Point3d poi = viewPoint.getPointOfInterest();
159            Vector3d vectorVPtoPOI = new Vector3d();
160            vectorVPtoPOI.sub( poi, vp );
161            
162            Transform3D trans = new Transform3D();
163            
164            // rotation at angleJ (vertikal) 
165            Vector3d rotJ = new Vector3d();
166            Vector3d eZ = new Vector3d(0,0,1) ;
167            rotJ.cross( vectorVPtoPOI, eZ );
168            AxisAngle4d axisAngleJ = new AxisAngle4d( rotJ, angleJ );        
169            trans.set(axisAngleJ);
170            trans.transform(vectorVPtoPOI);
171            
172            //rotation at angleI (horizontal)
173            Vector3d rotI = new Vector3d();
174            rotI.cross( vectorVPtoPOI, rotJ );
175            AxisAngle4d axisAngleI = new AxisAngle4d( rotI, angleI );        
176            trans.set(axisAngleI);
177            trans.transform(vectorVPtoPOI);
178    
179            // scale to extension
180            vectorVPtoPOI.normalize();
181            vectorVPtoPOI.scale(extension);
182            Point3d endPoint = new Point3d();
183            
184            // add to the viewpoint
185            endPoint.add( vp, vectorVPtoPOI);
186            return endPoint;
187            }
188    }