001    /*----------------------------------------------------------------------------
002     This file is part of deegree, http://deegree.org/
003     Copyright (C) 2001-2009 by:
004       Department of Geography, University of Bonn
005     and
006       lat/lon GmbH
007    
008     This library is free software; you can redistribute it and/or modify it under
009     the terms of the GNU Lesser General Public License as published by the Free
010     Software Foundation; either version 2.1 of the License, or (at your option)
011     any later version.
012     This library is distributed in the hope that it will be useful, but WITHOUT
013     ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
014     FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
015     details.
016     You should have received a copy of the GNU Lesser General Public License
017     along with this library; if not, write to the Free Software Foundation, Inc.,
018     59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
019    
020     Contact information:
021    
022     lat/lon GmbH
023     Aennchenstr. 19, 53177 Bonn
024     Germany
025     http://lat-lon.de/
026    
027     Department of Geography, University of Bonn
028     Prof. Dr. Klaus Greve
029     Postfach 1147, 53001 Bonn
030     Germany
031     http://www.geographie.uni-bonn.de/deegree/
032    
033     e-mail: info@deegree.org
034    ----------------------------------------------------------------------------*/
035    
036    package org.deegree.ogcwebservices.wpvs.operation;
037    
038    import javax.media.j3d.PickShape;
039    import javax.media.j3d.Transform3D;
040    import javax.vecmath.AxisAngle4d;
041    import javax.vecmath.Point3d;
042    import javax.vecmath.Vector3d;
043    
044    import org.deegree.model.crs.CoordinateSystem;
045    import org.deegree.model.spatialschema.Geometry;
046    import org.deegree.model.spatialschema.GeometryException;
047    import org.deegree.ogcwebservices.wpvs.j3d.ViewPoint;
048    
049    /**
050     * This abstract class represents a geometry needed for Get3DFeatureInfoRequest. It contains the 3d geometry and its 2d
051     * projektion. The 2d geometry is required for WFS request, the 3d geometry for the final test of intersection.
052     *
053     * @version $Revision: $
054     * @author <a href="mailto:cordes@lat-lon.de">Lyn Buesching</a>
055     * @author last edited by: $Author: $
056     *
057     * @version 1.0. $Revision: $, $Date: $
058     *
059     */
060    public abstract class RequestGeometry {
061    
062        /**
063         * The the feature info request
064         */
065        protected Get3DFeatureInfo request;
066    
067        // begin point of the view ray
068        private Point3d beginPointLine;
069    
070        private CoordinateSystem crs;
071    
072        /**
073         *  geometry for wfs query
074         */
075        protected Geometry wfsReqGeom;
076    
077        /**
078         *  3d geometry: needed for final testing
079         */
080        protected PickShape pickshape;
081    
082        /**
083         * Constructor to initialize the attributes needed for all geometries
084         *
085         * @param request
086         *            the Get3DFeatureInfoRequest
087         */
088        public RequestGeometry( Get3DFeatureInfo request ) {
089            this.request = request;
090            crs = request.getGetViewRequestCopy().getCrs();
091            beginPointLine = new ViewPoint( request.getGetViewRequestCopy() ).getObserverPosition();
092        }
093    
094        /**
095         *
096         * @return the pickshape or <code>null</code> if it was not set.
097         */
098        public PickShape getPickshape() {
099            return pickshape;
100        }
101    
102        /**
103         * @return the geometry repsonse from the wfs-request or <code>null</code> if it was not set.
104         */
105        public Geometry getWfsReqGeom() {
106            return wfsReqGeom;
107        }
108    
109        /**
110         * @return the starting point of the line.
111         */
112        public Point3d getBeginPointLine() {
113            return beginPointLine;
114        }
115    
116        /**
117         * @return the crs of the request.
118         */
119        public CoordinateSystem getCrs() {
120            return crs;
121        }
122    
123        /**
124         * @return the request.
125         */
126        public Get3DFeatureInfo getRequest() {
127            return request;
128        }
129    
130        // abstract methods
131        /**
132         * sets the geometry needed for WFS request
133         *
134         * @throws GeometryException
135         *             if something went wrong.
136         */
137        public abstract void setWfsReqGeom()
138                                            throws GeometryException;
139    
140        /**
141         * Sets the geometry needed for final test of intersection
142         */
143        public abstract void setPickshape();
144    
145        /**
146         * Calculates a ray through the ViewPoint and the ClickPoint.
147         *
148         * @param viewPoint
149         *            position of the request
150         * @param depth
151         *            far clipping plane
152         * @param width
153         *            of the request
154         * @param height
155         *            of the request
156         * @param clickI
157         *            x-axis
158         * @param clickJ
159         *            y-axis
160         * @return The end point of the requestGeometry.
161         */
162        protected Point3d calcEndPoint( ViewPoint viewPoint, double depth, int width, int height, int clickI, int clickJ ) {
163            // sets extension of the ray
164            double extension = viewPoint.getFarClippingPlane();
165            if ( depth > 0 && depth < extension ) {
166                extension = depth;
167            }
168            GetView getView = request.getGetViewRequestCopy();
169    
170            // rotates the cklickpoint to the roll-angle
171            double roll = getView.getRoll();
172            double deltaI = -( width / 2 ) + clickI;
173            double deltaJ = ( height / 2 ) - clickJ;
174    
175            double x = deltaI * Math.cos( roll ) + deltaJ * Math.sin( roll );
176            double y = -deltaI * Math.sin( roll ) + deltaJ * Math.cos( roll );
177    
178            // calculates the angles to rotate the vector (vp-poi)
179            double aov = viewPoint.getAngleOfView();
180            double distProj = ( width / 2 ) / Math.tan( aov / 2 );
181    
182            double angleI = Math.atan( x / distProj );
183            double angleJ = Math.atan( y / distProj );
184    
185            Point3d vp = viewPoint.getObserverPosition();
186            Point3d poi = viewPoint.getPointOfInterest();
187            Vector3d vectorVPtoPOI = new Vector3d();
188            vectorVPtoPOI.sub( poi, vp );
189    
190            Transform3D trans = new Transform3D();
191    
192            // rotation at angleJ (vertikal)
193            Vector3d rotJ = new Vector3d();
194            Vector3d eZ = new Vector3d( 0, 0, 1 );
195            rotJ.cross( vectorVPtoPOI, eZ );
196            AxisAngle4d axisAngleJ = new AxisAngle4d( rotJ, angleJ );
197            trans.set( axisAngleJ );
198            trans.transform( vectorVPtoPOI );
199    
200            // rotation at angleI (horizontal)
201            Vector3d rotI = new Vector3d();
202            rotI.cross( vectorVPtoPOI, rotJ );
203            AxisAngle4d axisAngleI = new AxisAngle4d( rotI, angleI );
204            trans.set( axisAngleI );
205            trans.transform( vectorVPtoPOI );
206    
207            // scale to extension
208            vectorVPtoPOI.normalize();
209            vectorVPtoPOI.scale( extension );
210            Point3d endPoint = new Point3d();
211    
212            // add to the viewpoint
213            endPoint.add( vp, vectorVPtoPOI );
214            return endPoint;
215        }
216    }